This repository has been archived on 2024-10-29. You can view files and clone it, but cannot push or open issues or pull requests.
Files
scoresaber-reloadedv3/src/components/score/score-stats.tsx

91 lines
2.6 KiB
TypeScript
Raw Normal View History

2024-09-14 18:40:39 +01:00
import ScoreSaberLeaderboardToken from "@/common/model/token/scoresaber/score-saber-leaderboard-token";
import ScoreSaberScoreToken from "@/common/model/token/scoresaber/score-saber-score-token";
import { formatNumberWithCommas, formatPp } from "@/common/number-utils";
import { accuracyToColor } from "@/common/song-utils";
import StatValue from "@/components/stat-value";
import { XMarkIcon } from "@heroicons/react/24/solid";
import clsx from "clsx";
2024-09-12 18:47:19 +01:00
type Badge = {
name: string;
color?: (score: ScoreSaberScoreToken, leaderboard: ScoreSaberLeaderboardToken) => string | undefined;
2024-09-13 13:45:04 +01:00
create: (
2024-09-14 18:40:39 +01:00
score: ScoreSaberScoreToken,
leaderboard: ScoreSaberLeaderboardToken
2024-09-13 13:45:04 +01:00
) => string | React.ReactNode | undefined;
2024-09-12 18:47:19 +01:00
};
const badges: Badge[] = [
{
name: "PP",
color: () => {
return "bg-pp";
},
2024-09-14 18:40:39 +01:00
create: (score: ScoreSaberScoreToken) => {
const pp = score.pp;
if (pp === 0) {
return undefined;
}
return `${formatPp(pp)}pp`;
},
},
{
name: "Accuracy",
color: (score: ScoreSaberScoreToken, leaderboard: ScoreSaberLeaderboardToken) => {
const acc = (score.baseScore / leaderboard.maxScore) * 100;
return accuracyToColor(acc);
},
create: (score: ScoreSaberScoreToken, leaderboard: ScoreSaberLeaderboardToken) => {
const acc = (score.baseScore / leaderboard.maxScore) * 100;
2024-09-12 16:41:38 +01:00
return `${acc.toFixed(2)}%`;
},
},
{
name: "Score",
2024-09-14 18:40:39 +01:00
create: (score: ScoreSaberScoreToken) => {
2024-09-12 16:41:38 +01:00
return `${formatNumberWithCommas(score.baseScore)}`;
},
},
2024-09-12 18:47:19 +01:00
{
name: "",
create: () => undefined,
},
{
name: "",
create: () => undefined,
},
{
name: "Full Combo",
2024-09-14 18:40:39 +01:00
create: (score: ScoreSaberScoreToken) => {
const fullCombo = score.missedNotes === 0;
return (
2024-09-12 16:41:38 +01:00
<>
<p>{fullCombo ? <span className="text-green-400">FC</span> : formatNumberWithCommas(score.missedNotes)}</p>
<XMarkIcon className={clsx("w-5 h-5", fullCombo ? "hidden" : "text-red-400")} />
2024-09-12 16:41:38 +01:00
</>
);
},
},
];
type Props = {
2024-09-14 18:40:39 +01:00
score: ScoreSaberScoreToken;
leaderboard: ScoreSaberLeaderboardToken;
};
export default function ScoreStats({ score, leaderboard }: Props) {
return (
2024-09-12 18:47:19 +01:00
<div className={`grid grid-cols-3 grid-rows-2 gap-1 ml-0 lg:ml-2`}>
{badges.map((badge, index) => {
const toRender = badge.create(score, leaderboard);
2024-09-13 16:40:47 +01:00
const color = badge.color?.(score, leaderboard);
2024-09-12 18:47:19 +01:00
if (toRender === undefined) {
return <div key={index} />;
}
return <StatValue key={index} color={color} value={toRender} />;
2024-09-12 16:41:38 +01:00
})}
</div>
);
}