Add winrates to seasons page

This commit is contained in:
Kalle
2023-08-19 17:04:45 +03:00
parent 651684460d
commit 9fd199e1d8
4 changed files with 88 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
import { sql } from "~/db/sql";
const stm = sql.prepare(/* sql */ `
select
sum("wins") as "wins",
sum("losses") as "losses"
from
"MapResult"
where
"userId" = @userId
and "season" = @season
group by
"userId"
`);
export function seasonMapWinrateByUserId({
userId,
season,
}: {
userId: number;
season: number;
}): { wins: number; losses: number } {
return stm.get({ userId, season }) as any;
}

View File

@@ -0,0 +1,25 @@
import { sql } from "~/db/sql";
const stm = sql.prepare(/* sql */ `
select
(sum("setWins") / 4) as "wins",
(sum("setLosses") / 4) as "losses"
from
"PlayerResult"
where
"ownerUserId" = @userId
and "season" = @season
and "type" = 'ENEMY'
group by
"ownerUserId"
`);
export function seasonSetWinrateByUserId({
userId,
season,
}: {
userId: number;
season: number;
}): { wins: number; losses: number } {
return stm.get({ userId, season }) as any;
}

View File

@@ -44,6 +44,8 @@ import { rankedModesShort } from "~/modules/in-game-lists/modes";
import { seasonsMatesEnemiesByUserId } from "~/features/sendouq/queries/seasonsMatesEnemiesByUserId.server";
import Chart from "~/components/Chart";
import { AlertIcon } from "~/components/icons/Alert";
import { seasonMapWinrateByUserId } from "~/features/sendouq/queries/seasonMapWinrateByUserId.server";
import { seasonSetWinrateByUserId } from "~/features/sendouq/queries/seasonSetWinrateByUserId.server";
export const seasonsSearchParamsSchema = z.object({
page: z.coerce.number().default(1),
@@ -72,6 +74,10 @@ export const loader = async ({ params, request }: LoaderArgs) => {
return {
currentOrdinal: currentMMRByUserId({ season: 0, userId: user.id }),
winrates: {
maps: seasonMapWinrateByUserId({ season: 0, userId: user.id }),
sets: seasonSetWinrateByUserId({ season: 0, userId: user.id }),
},
skills: seasonAllMMRByUserId({ season: 0, userId: user.id }),
tier,
matches: {
@@ -121,6 +127,9 @@ export default function UserSeasonsPage() {
{data.currentOrdinal ? (
<div className="stack md">
<Rank currentOrdinal={data.currentOrdinal} />
{data.winrates.maps.wins + data.winrates.maps.losses > 0 ? (
<Winrates />
) : null}
{data.skills.length >= 3 ? <PowerChart /> : null}
</div>
) : null}
@@ -203,6 +212,28 @@ function SeasonHeader() {
);
}
function Winrates() {
const data = useLoaderData<typeof loader>();
const winrate = (wins: number, losses: number) =>
Math.round((wins / (wins + losses)) * 100);
return (
<div className="stack horizontal sm">
<div className="u__season__winrate">
<span className="text-theme text-xxs">Sets</span>{" "}
{data.winrates.sets.wins}W {data.winrates.sets.losses}L (
{winrate(data.winrates.sets.wins, data.winrates.sets.losses)}%)
</div>
<div className="u__season__winrate">
<span className="text-theme text-xxs">Maps</span>{" "}
{data.winrates.maps.wins}W {data.winrates.maps.losses}L (
{winrate(data.winrates.maps.wins, data.winrates.maps.losses)}%)
</div>
</div>
);
}
function Rank({ currentOrdinal }: { currentOrdinal: number }) {
const data = useLoaderData<typeof loader>();

View File

@@ -386,3 +386,11 @@
padding: var(--s-2-5) var(--s-2);
border-radius: var(--rounded);
}
.u__season__winrate {
background-color: var(--bg-lighter);
padding: var(--s-0-5) var(--s-2);
border-radius: var(--rounded);
font-size: var(--fonts-xs);
font-weight: var(--semi-bold);
}