feat: create leaderboard

This commit is contained in:
thomas
2024-03-30 13:33:11 +01:00
parent bf3866b705
commit 8561653850
9 changed files with 102 additions and 35 deletions

View File

@@ -54,19 +54,19 @@ export default defineConfig({
ru: 'Руководство' ru: 'Руководство'
} }
}, },
// { {
// label: 'Leaderboard', label: 'Leaderboard',
// autogenerate: { autogenerate: {
// directory: 'leaderboard', directory: 'leaderboard',
// collapsed: true collapsed: true
// }, },
// translations: { translations: {
// es: 'Leaderboard', es: 'Leaderboard',
// fr: 'Leaderboard', fr: 'Leaderboard',
// pt: 'Leaderboard', pt: 'Leaderboard',
// ru: 'Leaderboard' ru: 'Leaderboard'
// } }
// }, },
{ {
label: 'Challenges', label: 'Challenges',
autogenerate: { autogenerate: {

View File

@@ -1,18 +1,29 @@
<script> <script>
import { onMount } from 'svelte';
import UserBox from './UserBox.svelte'; import UserBox from './UserBox.svelte';
import Spinner from './Spinner.svelte';
import { token } from '../github/github-store';
let users = []; let users = [];
let loading = true; let loading = true;
let error = null; let error = null;
token.subscribe(token => {
if (token) {
fetchGitHubUsers();
}
})
async function fetchGitHubUsers() { async function fetchGitHubUsers() {
try { try {
const prCounts = {}; const prCounts = {};
let page = 1; let page = 1;
while (true) { while (true) {
const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+label:%22answer%22&per_page=200&page=${page}`); const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+label:%22answer%22&per_page=200&page=${page}`, {
headers: {
Authorization: `token ${$token}`
}
});
if (!response.ok) { if (!response.ok) {
throw new Error('API rate limit exceeded. Please try again in a few minutes.'); throw new Error('API rate limit exceeded. Please try again in a few minutes.');
} }
@@ -58,13 +69,10 @@
} }
onMount(() => {
fetchGitHubUsers();
});
</script> </script>
{#if loading} {#if loading}
<p>Loading...</p> <Spinner />
{:else if error} {:else if error}
<p>Error: {error}</p> <p>Error: {error}</p>
{:else} {:else}
@@ -84,6 +92,7 @@
justify-items: center; justify-items: center;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 1.5rem; gap: 1.5rem;
margin-top: 2rem;
} }
.challenge-number { .challenge-number {

View File

@@ -1,12 +1,19 @@
<script> <script>
import { onMount } from 'svelte';
import UserBox from './UserBox.svelte'; import UserBox from './UserBox.svelte';
import Spinner from './Spinner.svelte';
import { token } from '../github/github-store';
let users = []; let users = [];
let loading = true; let loading = true;
let error = null; let error = null;
token.subscribe(token => {
if (token) {
fetchGitHubUsers();
}
})
const createUser = (items) => { const createUser = (items) => {
const prCounts = {}; const prCounts = {};
items.forEach((pr) => { items.forEach((pr) => {
@@ -30,7 +37,11 @@
async function fetchGitHubUsers() { async function fetchGitHubUsers() {
try { try {
const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+label:%22challenge-creation%22`); const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+label:%22challenge-creation%22`, {
headers: {
Authorization: `token ${$token}`
}
});
if (!response.ok) { if (!response.ok) {
throw new Error('API rate limit exceeded. Please try again in a few minutes.'); throw new Error('API rate limit exceeded. Please try again in a few minutes.');
} }
@@ -42,19 +53,15 @@
loading = false; loading = false;
} }
} }
onMount(() => {
fetchGitHubUsers();
});
</script> </script>
{#if loading} {#if loading}
<p>Loading...</p> <Spinner />
{:else if error} {:else if error}
<p>Error: {error}</p> <p>Error: {error}</p>
{:else} {:else}
<div class="box not-content"> <div class="box not-content">
{#each users as { avatar, count, login, challengeNumber }, index} {#each users as { avatar, count, login }, index}
<UserBox {avatar} {login} {index}> <UserBox {avatar} {login} {index}>
{count} Challenges Created {count} Challenges Created
</UserBox> </UserBox>
@@ -68,5 +75,6 @@
justify-items: center; justify-items: center;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 1.5rem; gap: 1.5rem;
margin-top: 2rem;
} }
</style> </style>

View File

@@ -1,18 +1,29 @@
<script> <script>
import { onMount } from 'svelte';
import UserBox from './UserBox.svelte'; import UserBox from './UserBox.svelte';
import Spinner from './Spinner.svelte';
import { token } from '../github/github-store';
let users = []; let users = [];
let loading = true; let loading = true;
let error = null; let error = null;
token.subscribe(token => {
if (token) {
fetchGitHubUsers();
}
})
async function fetchGitHubUsers() { async function fetchGitHubUsers() {
try { try {
const prCounts = {}; const prCounts = {};
let page = 1; let page = 1;
while (true) { while (true) {
const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+no:label&per_page=100&page=${page}`); const response = await fetch(`https://api.github.com/search/issues?q=repo:tomalaforge/angular-challenges+is:pr+no:label&per_page=100&page=${page}`,{
headers: {
Authorization: `token ${$token}`
}
});
if (!response.ok) { if (!response.ok) {
throw new Error('API rate limit exceeded. Please try again in a few minutes.'); throw new Error('API rate limit exceeded. Please try again in a few minutes.');
} }
@@ -49,7 +60,7 @@
avatar: pr.avatar, avatar: pr.avatar,
count: pr.count, count: pr.count,
challengeNumber: pr.challengeNumber challengeNumber: pr.challengeNumber
})).filter((r) => r.login !== 'allcontributors[bot]').sort((a, b) => b.count - a.count); })).filter((r) => r.login !== 'allcontributors[bot]' && r.login !== 'tomalaforge').sort((a, b) => b.count - a.count);
} catch (e) { } catch (e) {
error = e.message; error = e.message;
@@ -58,14 +69,10 @@
} }
} }
onMount(() => {
fetchGitHubUsers();
});
</script> </script>
{#if loading} {#if loading}
<p>Loading...</p> <Spinner />
{:else if error} {:else if error}
<p>Error: {error}</p> <p>Error: {error}</p>
{:else} {:else}
@@ -84,5 +91,6 @@
justify-items: center; justify-items: center;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 1.5rem; gap: 1.5rem;
margin-top: 2rem;
} }
</style> </style>

View File

@@ -0,0 +1,33 @@
<div class="spinner-container">
<div class="spinner"></div>
</div>
<style>
.spinner-container {
margin-top: 2rem;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.spinner {
border: 4px solid var(--sl-color-gray-3); /* Light grey border */
border-top: 4px solid var(--sl-color-bg);
border-right: 4px solid var(--sl-color-bg);
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@@ -26,6 +26,7 @@ import MyIcon from '../../components/MyIcon.astro';
import SubscriptionForm from '../../components/SubscriptionForm.astro'; import SubscriptionForm from '../../components/SubscriptionForm.astro';
<CardGrid> <CardGrid>
<Card title="47 Challenges"> <Card title="47 Challenges">
This repository gathers 47 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>. This repository gathers 47 Challenges related to <b>Angular</b>, <b>Nx</b>, <b>RxJS</b>, <b>Ngrx</b> and <b>Typescript</b>.

View File

@@ -8,4 +8,6 @@ next: false
import LeaderboardAnswer from '../../../components/leaderboard/LeaderboardAnswer.svelte'; import LeaderboardAnswer from '../../../components/leaderboard/LeaderboardAnswer.svelte';
Join the list and start your Angular Challenges journey by reading the [Getting Started](/guides/getting-started) guide.
<LeaderboardAnswer client:load /> <LeaderboardAnswer client:load />

View File

@@ -8,4 +8,7 @@ next: false
import LeaderboardChallenge from '../../../components/leaderboard/LeaderboardChallenge.svelte'; import LeaderboardChallenge from '../../../components/leaderboard/LeaderboardChallenge.svelte';
A challenge is missing, create your own one and get on the leaderboard!
Read the [Create Challenge](/guides/create-challenge) guide to learn how to create a challenge.
<LeaderboardChallenge client:load /> <LeaderboardChallenge client:load />

View File

@@ -8,4 +8,7 @@ next: false
import LeaderboardCommit from '../../../components/leaderboard/LeaderboardCommit.svelte'; import LeaderboardCommit from '../../../components/leaderboard/LeaderboardCommit.svelte';
You want to improve the project, fix a typo, add some documentation to one challenges, or translate a page? This leaderboard shows the number of contributions per user.
This repository is open source and you can contribute to it. Read the [contribution](/guides/contribute) guide to get started.
<LeaderboardCommit client:load /> <LeaderboardCommit client:load />