From 131a08251f187f046b9eb1848583af349f90c188 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Thu, 17 Sep 2026 23:49:56 -0400 Subject: [PATCH] feature: faceit and premier leaderboard tabs Both are cached ratings rather than match statistics, so the match filter bar is hidden for them, and each tab only appears where the platform collects it. --- i18n/locales/ar_SA.json | 9 ++++++-- i18n/locales/da_DK.json | 9 ++++++-- i18n/locales/de_DE.json | 9 ++++++-- i18n/locales/en.json | 9 ++++++-- i18n/locales/es_ES.json | 9 ++++++-- i18n/locales/fr_FR.json | 9 ++++++-- i18n/locales/it_IT.json | 9 ++++++-- i18n/locales/ja_JP.json | 9 ++++++-- i18n/locales/ko_KR.json | 9 ++++++-- i18n/locales/pl_PL.json | 9 ++++++-- i18n/locales/pt_BR.json | 9 ++++++-- i18n/locales/ru_RU.json | 9 ++++++-- i18n/locales/sv_SE.json | 9 ++++++-- i18n/locales/tr_TR.json | 9 ++++++-- i18n/locales/uk_UA.json | 9 ++++++-- i18n/locales/zh_Hans.json | 9 ++++++-- i18n/locales/zh_Hant.json | 9 ++++++-- pages/leaderboard.vue | 43 ++++++++++++++++++++++++++++++++++----- 18 files changed, 157 insertions(+), 39 deletions(-) diff --git a/i18n/locales/ar_SA.json b/i18n/locales/ar_SA.json index ebe59cdcc..f9a29e9f7 100644 --- a/i18n/locales/ar_SA.json +++ b/i18n/locales/ar_SA.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "نسبة الفوز", "highest_hs_pct": "HS%", - "awards": "الكؤوس" + "awards": "الكؤوس", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "آخر 7 أيام", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "ضرر العتاد", - "rounds": "جولات" + "rounds": "جولات", + "faceit_elo": "Faceit ELO", + "faceit_level": "المستوى", + "premier_rank": "Premier الرتبة" }, "exclude_tournaments": "استثناء البطولات" }, diff --git a/i18n/locales/da_DK.json b/i18n/locales/da_DK.json index 763c2186f..de3055bc0 100644 --- a/i18n/locales/da_DK.json +++ b/i18n/locales/da_DK.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Sejrsrate", "highest_hs_pct": "HS%", - "awards": "Trofæer" + "awards": "Trofæer", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Seneste 7 dage", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Util-dmg", - "rounds": "Runder" + "rounds": "Runder", + "faceit_elo": "Faceit ELO", + "faceit_level": "Niveau", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Udelad turneringer" }, diff --git a/i18n/locales/de_DE.json b/i18n/locales/de_DE.json index be8e5b424..968e7492c 100644 --- a/i18n/locales/de_DE.json +++ b/i18n/locales/de_DE.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Siegrate", "highest_hs_pct": "HS%", - "awards": "Auszeichnungen" + "awards": "Auszeichnungen", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Letzte 7 Tage", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Util-Dmg", - "rounds": "Runden" + "rounds": "Runden", + "faceit_elo": "Faceit ELO", + "faceit_level": "Level", + "premier_rank": "Premier Rang" }, "exclude_tournaments": "Turniere ausschließen" }, diff --git a/i18n/locales/en.json b/i18n/locales/en.json index fc6f624ac..2f577a464 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Win Rate", "highest_hs_pct": "HS%", - "awards": "Awards" + "awards": "Awards", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Last 7 Days", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Util Dmg", - "rounds": "Rounds" + "rounds": "Rounds", + "faceit_elo": "Faceit ELO", + "faceit_level": "Level", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Exclude Tournaments" }, diff --git a/i18n/locales/es_ES.json b/i18n/locales/es_ES.json index e5995316b..24677dee2 100644 --- a/i18n/locales/es_ES.json +++ b/i18n/locales/es_ES.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Victorias %", "highest_hs_pct": "HS%", - "awards": "Trofeos" + "awards": "Trofeos", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Últimos 7 días", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Daño util.", - "rounds": "Rondas" + "rounds": "Rondas", + "faceit_elo": "Faceit ELO", + "faceit_level": "Nivel", + "premier_rank": "Premier Rango" }, "exclude_tournaments": "Excluir torneos" }, diff --git a/i18n/locales/fr_FR.json b/i18n/locales/fr_FR.json index 343a5e45f..eff1654c2 100644 --- a/i18n/locales/fr_FR.json +++ b/i18n/locales/fr_FR.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Taux de victoire", "highest_hs_pct": "HS%", - "awards": "Récompenses" + "awards": "Récompenses", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "7 derniers jours", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Dégâts util.", - "rounds": "Rounds" + "rounds": "Rounds", + "faceit_elo": "Faceit ELO", + "faceit_level": "Niveau", + "premier_rank": "Premier Rang" }, "exclude_tournaments": "Exclure les tournois" }, diff --git a/i18n/locales/it_IT.json b/i18n/locales/it_IT.json index 2b779ad62..2e32cf149 100644 --- a/i18n/locales/it_IT.json +++ b/i18n/locales/it_IT.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "% vittorie", "highest_hs_pct": "HS%", - "awards": "Trofei" + "awards": "Trofei", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Ultimi 7 giorni", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Danni utility", - "rounds": "Round" + "rounds": "Round", + "faceit_elo": "Faceit ELO", + "faceit_level": "Livello", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Escludi tornei" }, diff --git a/i18n/locales/ja_JP.json b/i18n/locales/ja_JP.json index bf33f2526..355c1523e 100644 --- a/i18n/locales/ja_JP.json +++ b/i18n/locales/ja_JP.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "勝率", "highest_hs_pct": "HS%", - "awards": "アワード" + "awards": "アワード", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "過去7日間", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "util与ダメ", - "rounds": "ラウンド" + "rounds": "ラウンド", + "faceit_elo": "Faceit ELO", + "faceit_level": "レベル", + "premier_rank": "Premier ランク" }, "exclude_tournaments": "トーナメントを除外" }, diff --git a/i18n/locales/ko_KR.json b/i18n/locales/ko_KR.json index fb7ef8d5e..8a8cb205a 100644 --- a/i18n/locales/ko_KR.json +++ b/i18n/locales/ko_KR.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "승률", "highest_hs_pct": "HS%", - "awards": "어워드" + "awards": "어워드", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "최근 7일", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "유틸 데미지", - "rounds": "라운드" + "rounds": "라운드", + "faceit_elo": "Faceit ELO", + "faceit_level": "레벨", + "premier_rank": "Premier 랭크" }, "exclude_tournaments": "토너먼트 제외" }, diff --git a/i18n/locales/pl_PL.json b/i18n/locales/pl_PL.json index a0307a782..3c848c002 100644 --- a/i18n/locales/pl_PL.json +++ b/i18n/locales/pl_PL.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Win rate", "highest_hs_pct": "HS%", - "awards": "Nagrody" + "awards": "Nagrody", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Ostatnie 7 dni", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Obrażenia utility", - "rounds": "Rundy" + "rounds": "Rundy", + "faceit_elo": "Faceit ELO", + "faceit_level": "Poziom", + "premier_rank": "Premier Ranga" }, "exclude_tournaments": "Wyklucz turnieje" }, diff --git a/i18n/locales/pt_BR.json b/i18n/locales/pt_BR.json index 9e310fd44..9641e4c14 100644 --- a/i18n/locales/pt_BR.json +++ b/i18n/locales/pt_BR.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Taxa de Vitória", "highest_hs_pct": "% HS", - "awards": "Troféus" + "awards": "Troféus", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Ultimos 7 dias", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Dano de Util", - "rounds": "Rodadas" + "rounds": "Rodadas", + "faceit_elo": "Faceit ELO", + "faceit_level": "Nível", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Excluir Torneios" }, diff --git a/i18n/locales/ru_RU.json b/i18n/locales/ru_RU.json index d049d2045..dbf8b7b91 100644 --- a/i18n/locales/ru_RU.json +++ b/i18n/locales/ru_RU.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Процент побед", "highest_hs_pct": "HS%", - "awards": "Награды" + "awards": "Награды", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Последние 7 дней", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Урон гранатами", - "rounds": "Раунды" + "rounds": "Раунды", + "faceit_elo": "Faceit ELO", + "faceit_level": "Уровень", + "premier_rank": "Premier Ранг" }, "exclude_tournaments": "Исключить турниры" }, diff --git a/i18n/locales/sv_SE.json b/i18n/locales/sv_SE.json index 316fe396a..f4e0064c4 100644 --- a/i18n/locales/sv_SE.json +++ b/i18n/locales/sv_SE.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Vinstandel", "highest_hs_pct": "HS%", - "awards": "Utmärkelser" + "awards": "Utmärkelser", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Senaste 7 dagarna", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Utility-skada", - "rounds": "Ronder" + "rounds": "Ronder", + "faceit_elo": "Faceit ELO", + "faceit_level": "Nivå", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Exkludera turneringar" }, diff --git a/i18n/locales/tr_TR.json b/i18n/locales/tr_TR.json index 5499d27a6..348d4dcdb 100644 --- a/i18n/locales/tr_TR.json +++ b/i18n/locales/tr_TR.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Galibiyet oranı", "highest_hs_pct": "HS%", - "awards": "Ödüller" + "awards": "Ödüller", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Son 7 gün", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Ekipman hasarı", - "rounds": "Raunt" + "rounds": "Raunt", + "faceit_elo": "Faceit ELO", + "faceit_level": "Seviye", + "premier_rank": "Premier Rank" }, "exclude_tournaments": "Turnuvaları hariç tut" }, diff --git a/i18n/locales/uk_UA.json b/i18n/locales/uk_UA.json index 1561a2f6f..9b630bbd4 100644 --- a/i18n/locales/uk_UA.json +++ b/i18n/locales/uk_UA.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "Відсоток перемог", "highest_hs_pct": "HS%", - "awards": "Нагороди" + "awards": "Нагороди", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "Останні 7 днів", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "Шкода гранат", - "rounds": "Раунди" + "rounds": "Раунди", + "faceit_elo": "Faceit ELO", + "faceit_level": "Рівень", + "premier_rank": "Premier Ранг" }, "exclude_tournaments": "Виключити турніри" }, diff --git a/i18n/locales/zh_Hans.json b/i18n/locales/zh_Hans.json index 54df420e8..d16943934 100644 --- a/i18n/locales/zh_Hans.json +++ b/i18n/locales/zh_Hans.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "胜率", "highest_hs_pct": "爆头率", - "awards": "奖杯" + "awards": "奖杯", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "最近 7 天", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "道具伤害", - "rounds": "回合" + "rounds": "回合", + "faceit_elo": "Faceit ELO", + "faceit_level": "等级", + "premier_rank": "Premier 排名" }, "exclude_tournaments": "排除赛事" }, diff --git a/i18n/locales/zh_Hant.json b/i18n/locales/zh_Hant.json index 43580de2b..5031b9ab8 100644 --- a/i18n/locales/zh_Hant.json +++ b/i18n/locales/zh_Hant.json @@ -3547,7 +3547,9 @@ "best_kdr": "KDR", "best_win_rate": "勝率", "highest_hs_pct": "HS%", - "awards": "獎項" + "awards": "獎項", + "faceit_elo": "Faceit", + "premier_rank": "Premier" }, "time_periods": { "last_7_days": "最近 7 天", @@ -3602,7 +3604,10 @@ "kast": "KAST", "udr": "UDR", "util_damage": "道具傷害", - "rounds": "回合" + "rounds": "回合", + "faceit_elo": "Faceit ELO", + "faceit_level": "等級", + "premier_rank": "Premier 排名" }, "exclude_tournaments": "排除賽事" }, diff --git a/pages/leaderboard.vue b/pages/leaderboard.vue index ea5baf22a..1f1be3885 100644 --- a/pages/leaderboard.vue +++ b/pages/leaderboard.vue @@ -97,6 +97,19 @@ const CATEGORY_CONFIG: Record< sortable: SortField[]; } > = { + faceit_elo: { + columns: { + value: "pages.leaderboard.col.faceit_elo", + secondary_value: "pages.leaderboard.col.faceit_level", + }, + sortable: ["value", "secondary_value"], + }, + premier_rank: { + columns: { + value: "pages.leaderboard.col.premier_rank", + }, + sortable: ["value"], + }, elo: { columns: { value: "pages.leaderboard.col.elo", @@ -344,6 +357,8 @@ type Season = { starts_at: string; ends_at: string | null; }; +const appSettings = useApplicationSettingsStore(); + const seasonsEnabled = computed( () => useApplicationSettingsStore().seasonsEnabled, ); @@ -377,7 +392,17 @@ const roleFilter = ref(readQueryParam("role", ROLE_OPTIONS, "all")); const sourceFilter = ref( readQueryParam("source", SOURCE_OPTIONS, "overall"), ); -const supportsRole = computed(() => ROLE_CATEGORIES.has(category.value)); +const supportsRole = computed( + () => ROLE_CATEGORIES.has(category.value) && !isExternalRank.value, +); + +// FACEIT ratings and Premier ranks are snapshots we cache from elsewhere, not +// anything derived from matches played here, so none of the match filters mean +// anything for them - showing a scope of "last 7 days" would read as applied. +const EXTERNAL_RANK_CATEGORIES = new Set(["faceit_elo", "premier_rank"]); +const isExternalRank = computed(() => + EXTERNAL_RANK_CATEGORIES.has(category.value), +); // Default to the current season when seasons are on and one is active; otherwise // fall back to All Time (systems without a current season). @@ -454,7 +479,10 @@ const highlightedSteamId = computed(() => { }); let fetchGeneration = 0; -const categories = [ +// The two external ratings are only offered where the platform actually +// collects them: FACEIT needs the import turned on, Premier ranks come out of +// imported Valve demos. +const categories = computed(() => [ { value: "elo" }, { value: "best_rating" }, { value: "best_adr" }, @@ -465,7 +493,9 @@ const categories = [ { value: "best_win_rate" }, { value: "highest_hs_pct" }, { value: "awards" }, -]; + ...(appSettings.faceitEnabled ? [{ value: "faceit_elo" }] : []), + ...(appSettings.linkedAccountsEnabled ? [{ value: "premier_rank" }] : []), +]); const config = computed(() => CATEGORY_CONFIG[category.value]); @@ -683,6 +713,8 @@ function formatValue(value: number): string { case "best_kast": return value.toFixed(1) + "%"; case "awards": + case "faceit_elo": + case "premier_rank": return Math.round(value).toLocaleString(); default: return String(value); @@ -861,8 +893,9 @@ onMounted(async () => { - - + +