mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 07:37:55 -05:00
Add Season 13 data
This commit is contained in:
@@ -205,19 +205,10 @@ function TournamentShowcase() {
|
||||
}
|
||||
|
||||
function ResultHighlights() {
|
||||
const { t } = useTranslation(["front", "common"]);
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
// should not happen
|
||||
if (
|
||||
!data.leaderboards.team.length ||
|
||||
!data.leaderboards.user.length ||
|
||||
!data.tournaments.results.length
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const season = Seasons.currentOrPrevious()!;
|
||||
const hasLeaderboards =
|
||||
data.leaderboards.user.length > 0 && data.leaderboards.team.length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -229,52 +220,74 @@ function ResultHighlights() {
|
||||
)}
|
||||
>
|
||||
<SeasonCard />
|
||||
<div className="stack sm text-center">
|
||||
<h2 className={styles.resultHighlightsTitle}>
|
||||
{t("front:leaderboards.topPlayers")}
|
||||
</h2>
|
||||
<Leaderboard
|
||||
entries={data.leaderboards.user}
|
||||
fullLeaderboardUrl={leaderboardsPage({
|
||||
season: season.nth,
|
||||
type: "USER",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="stack sm text-center">
|
||||
<h2 className={styles.resultHighlightsTitle}>
|
||||
{t("front:leaderboards.topTeams")}
|
||||
</h2>
|
||||
<Leaderboard
|
||||
entries={data.leaderboards.team}
|
||||
fullLeaderboardUrl={leaderboardsPage({
|
||||
season: season.nth,
|
||||
type: "TEAM",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
{hasLeaderboards ? <Leaderboards /> : null}
|
||||
</div>
|
||||
<div className={clsx(styles.resultHighlights, "scrollbar")}>
|
||||
<div className="stack sm text-center">
|
||||
<h2
|
||||
className={clsx(
|
||||
styles.resultHighlightsTitle,
|
||||
styles.resultHighlightsTitleTournaments,
|
||||
)}
|
||||
>
|
||||
{t("front:showcase.results")}
|
||||
</h2>
|
||||
<div className={clsx(styles.tournamentCardsSpacer, "scrollbar")}>
|
||||
{data.tournaments.results.map((tournament) => (
|
||||
<TournamentCard key={tournament.id} tournament={tournament} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{data.tournaments.results.length > 0 ? <TournamentResults /> : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Leaderboards() {
|
||||
const { t } = useTranslation(["front"]);
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
const season = Seasons.currentOrPrevious()!;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="stack sm text-center">
|
||||
<h2 className={styles.resultHighlightsTitle}>
|
||||
{t("front:leaderboards.topPlayers")}
|
||||
</h2>
|
||||
<Leaderboard
|
||||
entries={data.leaderboards.user}
|
||||
fullLeaderboardUrl={leaderboardsPage({
|
||||
season: season.nth,
|
||||
type: "USER",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="stack sm text-center">
|
||||
<h2 className={styles.resultHighlightsTitle}>
|
||||
{t("front:leaderboards.topTeams")}
|
||||
</h2>
|
||||
<Leaderboard
|
||||
entries={data.leaderboards.team}
|
||||
fullLeaderboardUrl={leaderboardsPage({
|
||||
season: season.nth,
|
||||
type: "TEAM",
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function TournamentResults() {
|
||||
const { t } = useTranslation(["front"]);
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
return (
|
||||
<div className={clsx(styles.resultHighlights, "scrollbar")}>
|
||||
<div className="stack sm text-center">
|
||||
<h2
|
||||
className={clsx(
|
||||
styles.resultHighlightsTitle,
|
||||
styles.resultHighlightsTitleTournaments,
|
||||
)}
|
||||
>
|
||||
{t("front:showcase.results")}
|
||||
</h2>
|
||||
<div className={clsx(styles.tournamentCardsSpacer, "scrollbar")}>
|
||||
{data.tournaments.results.map((tournament) => (
|
||||
<TournamentCard key={tournament.id} tournament={tournament} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Leaderboard({
|
||||
entries,
|
||||
fullLeaderboardUrl,
|
||||
|
||||
@@ -106,6 +106,11 @@ export const list =
|
||||
starts: new Date("2026-06-01T17:00:00.000Z"),
|
||||
ends: new Date("2026-08-23T22:00:00.000Z"),
|
||||
},
|
||||
{
|
||||
nth: 13,
|
||||
starts: new Date("2026-09-01T17:00:00.000Z"),
|
||||
ends: new Date("2026-11-22T22:00:00.000Z"),
|
||||
},
|
||||
] as const);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,11 +2,21 @@ import { afterAll, beforeAll, vi } from "vitest";
|
||||
import * as Seasons from "~/features/mmr/core/Seasons";
|
||||
import invariant from "~/utils/invariant";
|
||||
|
||||
const lastSeason = Seasons.list[Seasons.list.length - 1];
|
||||
invariant(lastSeason, "Expected at least one season");
|
||||
const startedSeasons = Seasons.list.filter(
|
||||
(season) => season.starts.getTime() <= Date.now(),
|
||||
);
|
||||
const latestStartedSeason = startedSeasons[startedSeasons.length - 1];
|
||||
invariant(latestStartedSeason, "Expected at least one started season");
|
||||
|
||||
// the database stamps its own rows with the real "now", so a pinned time in the
|
||||
// future would make every one of them look long expired
|
||||
const insideASeason = new Date(
|
||||
(lastSeason.starts.getTime() + lastSeason.ends.getTime()) / 2,
|
||||
Math.min(
|
||||
(latestStartedSeason.starts.getTime() +
|
||||
latestStartedSeason.ends.getTime()) /
|
||||
2,
|
||||
Date.now(),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
|
||||
.seasonBannerImg {
|
||||
position: absolute;
|
||||
width: 109px;
|
||||
right: -5px;
|
||||
width: 84px;
|
||||
right: 4px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@@ -180,6 +180,12 @@
|
||||
.resultHighlightsTop {
|
||||
--card-width: 100%;
|
||||
overflow-x: auto;
|
||||
|
||||
/* on a season's first day the leaderboards are still empty, leaving the card
|
||||
alone in the row with nothing beside it to stretch against */
|
||||
& > .seasonCardDesktopOnly:only-child {
|
||||
max-width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.resultHighlightsTitle {
|
||||
@@ -194,6 +200,11 @@
|
||||
.seasonCard {
|
||||
--l: 50%;
|
||||
|
||||
/* see .resultHighlightsTop: alone in the row it collapses to its text */
|
||||
.seasonCardDesktopOnly:only-child & {
|
||||
min-height: 250px;
|
||||
}
|
||||
|
||||
min-width: var(--card-width);
|
||||
max-width: var(--card-width);
|
||||
flex: 1;
|
||||
@@ -232,7 +243,7 @@
|
||||
|
||||
.seasonCardImg {
|
||||
position: absolute;
|
||||
width: 175px;
|
||||
width: 150px;
|
||||
bottom: 0;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user