Skip to content

Commit 64edb9d

Browse files
committed
feat(leaderboard): show accurate stage counts and add header explanations
Replace all uses of stagesCount with liveOrBetaStagesCount to reflect only live or beta course stages. This improves accuracy of displayed stage numbers across leaderboard and track cards. Move stage count and score explanation tooltips into a dedicated header row component for better structure and reusability. Update header cells to display explanations for "Stages Completed" and "Score" to clarify scoring and stage availability to users.
1 parent 7170243 commit 64edb9d

File tree

9 files changed

+51
-35
lines changed

9 files changed

+51
-35
lines changed

app/components/leaderboard-page/entries-table.hbs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,7 @@
33
<div>
44
<table class="min-w-full bg-white">
55
<thead>
6-
<tr>
7-
<LeaderboardPage::EntriesTable::HeaderRowCell @title="Rank" @alignment="left" />
8-
<LeaderboardPage::EntriesTable::HeaderRowCell @title="User" @alignment="left" />
9-
10-
<LeaderboardPage::EntriesTable::HeaderRowCell
11-
@title="Stages Completed"
12-
@alignment="right"
13-
class="hidden md:table-cell"
14-
@explanationMarkdown={{this.explanationMarkdownForStagesCompleted}}
15-
/>
16-
17-
<LeaderboardPage::EntriesTable::HeaderRowCell
18-
@title="Score"
19-
@alignment="right"
20-
@explanationMarkdown={{this.explanationMarkdownForScore}}
21-
/>
22-
</tr>
6+
<LeaderboardPage::EntriesTable::HeaderRow @language={{this.language}} />
237
</thead>
248
<tbody>
259
{{#each this.sortedTopEntries as |entry index|}}

app/components/leaderboard-page/entries-table.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,6 @@ export default class LeaderboardPageEntriesTable extends Component<Signature> {
3232
}
3333
}
3434

35-
get explanationMarkdownForScore() {
36-
return `
37-
The highest possible score for this track is ${this.args.language.leaderboard!.highestPossibleScore}.
38-
39-
Harder stages have higher scores assigned to them.
40-
`.trim();
41-
}
42-
43-
get explanationMarkdownForStagesCompleted() {
44-
return `There are ${this.args.language.stagesCount} stages available in this track.`;
45-
}
46-
4735
get hasEntries() {
4836
return this.args.topEntries.length > 0;
4937
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<tr ...attributes>
2+
<LeaderboardPage::EntriesTable::HeaderRowCell @title="Rank" @alignment="left" />
3+
<LeaderboardPage::EntriesTable::HeaderRowCell @title="User" @alignment="left" />
4+
5+
<LeaderboardPage::EntriesTable::HeaderRowCell
6+
@title="Stages Completed"
7+
@alignment="right"
8+
class="hidden md:table-cell"
9+
@explanationMarkdown={{this.explanationMarkdownForStagesCompleted}}
10+
/>
11+
12+
<LeaderboardPage::EntriesTable::HeaderRowCell @title="Score" @alignment="right" @explanationMarkdown={{this.explanationMarkdownForScore}} />
13+
</tr>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Component from '@glimmer/component';
2+
import type LanguageModel from 'codecrafters-frontend/models/language';
3+
4+
interface Signature {
5+
Element: HTMLTableRowElement;
6+
7+
Args: {
8+
language: LanguageModel;
9+
};
10+
}
11+
12+
export default class LeaderboardPageEntriesTableHeaderRow extends Component<Signature> {
13+
get explanationMarkdownForScore() {
14+
return `
15+
The highest possible score for this track is ${this.args.language.leaderboard!.highestPossibleScore}.
16+
17+
Harder stages have higher scores assigned to them.
18+
`.trim();
19+
}
20+
21+
get explanationMarkdownForStagesCompleted() {
22+
return `There are ${this.args.language.liveOrBetaStagesCount} stages available in this track.`;
23+
}
24+
}
25+
26+
declare module '@glint/environment-ember-loose/registry' {
27+
export default interface Registry {
28+
'LeaderboardPage::EntriesTable::HeaderRow': typeof LeaderboardPageEntriesTableHeaderRow;
29+
}
30+
}

app/components/leaderboard-page/header.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default class LeaderboardPageHeader extends Component<Signature> {
2121
return this.store
2222
.peekAll('language')
2323
.sortBy('sortPositionForTrack')
24-
.filter((language) => language.stagesCount > 0);
24+
.filter((language) => language.liveOrBetaStagesCount > 0);
2525
}
2626

2727
@action

app/components/track-page/header/index.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
{{/if}}
2828
{{/if}}
2929

30-
<TrackPage::Header::Statistic @description="{{format-number @language.stagesCount}} exercises" @icon="terminal" class="shrink-0" />
30+
<TrackPage::Header::Statistic @description="{{format-number @language.liveOrBetaStagesCount}} exercises" @icon="terminal" class="shrink-0" />
3131
</div>
3232

3333
{{#if (has-block "cta")}}

app/components/tracks-page/track-card/index.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
{{! Footer }}
2929
<div class="flex items-center justify-between">
3030
{{#if this.currentUserHasStartedTrack}}
31-
<TracksPage::TrackCard::ProgressBar @completedStagesCount={{this.completedStagesCount}} @stagesCount={{this.stagesCount}} />
31+
<TracksPage::TrackCard::ProgressBar @completedStagesCount={{this.completedStagesCount}} @stagesCount={{this.liveOrBetaStagesCount}} />
3232
{{else}}
3333
<div class="flex items-center">
3434
{{svg-jar "academic-cap" class="w-4 mr-1 fill-current text-gray-400 dark:text-gray-600"}}
35-
<span class="text-xs text-gray-500">{{this.stagesCount}} stages</span>
35+
<span class="text-xs text-gray-500">{{this.liveOrBetaStagesCount}} stages</span>
3636
</div>
3737
{{/if}}
3838

app/controllers/leaderboard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export default class LeaderboardController extends Controller {
1313
return this.store
1414
.peekAll('language')
1515
.sortBy('sortPositionForTrack')
16-
.filter((language) => language.stagesCount > 0);
16+
.filter((language) => language.liveOrBetaStagesCount > 0);
1717
}
1818
}

app/models/language.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ export default class LanguageModel extends Model {
164164
].join('');
165165
}
166166

167-
get stagesCount() {
167+
get liveOrBetaStagesCount() {
168168
return this.store
169169
.peekAll('course')
170+
.filter((course) => course.releaseStatusIsLive || course.releaseStatusIsBeta)
170171
.filter((course) => course.betaOrLiveLanguages.includes(this))
171172
.map((course) => course.stages.length)
172173
.reduce((a, b) => a + b, 0);

0 commit comments

Comments
 (0)