change theme color (again) and add acc colors to the score stat badges
Some checks failed
Deploy SSR / deploy (push) Failing after 30s

This commit is contained in:
Lee 2024-09-13 14:22:51 +01:00
parent 86252150b8
commit 671f520635
5 changed files with 63 additions and 20 deletions

@ -1,3 +1,25 @@
export const diffColors: Record<string, string> = {
easy: "MediumSeaGreen",
normal: "#59b0f4",
hard: "tomato",
expert: "#bf2a42",
expertPlus: "#8f48db",
};
const badgesDef: {
name: string;
min: number | null;
max: number | null;
color: string;
}[] = [
{ name: "SS+", min: 95, max: null, color: diffColors.expertPlus },
{ name: "SS", min: 90, max: 95, color: diffColors.expert },
{ name: "S+", min: 85, max: 90, color: diffColors.hard },
{ name: "S", min: 80, max: 85, color: diffColors.normal },
{ name: "A", min: 70, max: 80, color: diffColors.easy },
{ name: "-", min: null, max: 70, color: "hsl(var(--accent))" },
];
/** /**
* Turns the difficulty of a song into a color * Turns the difficulty of a song into a color
* *
@ -5,18 +27,24 @@
* @returns the color for the difficulty * @returns the color for the difficulty
*/ */
export function songDifficultyToColor(diff: string) { export function songDifficultyToColor(diff: string) {
switch (diff.toLowerCase()) { diff = diff.replace("+", "Plus");
case "easy": return diffColors[diff.toLowerCase() as keyof typeof diffColors];
return "#3cb371"; }
case "normal":
return "#59b0f4"; /**
case "hard": * Formats the accuracy into a color
return "#FF6347"; *
case "expert": * @param acc the accuracy to get the color for
return "#bf2a42"; */
case "expert+": export function accuracyToColor(acc: number): string {
return "#8f48db"; for (const badge of badgesDef) {
default: if (
return "gray"; (badge.min === null || acc >= badge.min) &&
} (badge.max === null || acc < badge.max)
) {
return badge.color;
}
}
// Return a default color if no badge matches
return "#000000"; // black or any default color
} }

@ -114,7 +114,7 @@ export default function PlayerRankChart({ player }: Props) {
lineTension: 0.5, lineTension: 0.5,
data: playerRankHistory, data: playerRankHistory,
label: "Rank", label: "Rank",
borderColor: "#a147fa", borderColor: "#606fff",
fill: false, fill: false,
color: "#fff", color: "#fff",
}, },

@ -4,9 +4,14 @@ import { formatNumberWithCommas } from "@/common/number-utils";
import StatValue from "@/components/stat-value"; import StatValue from "@/components/stat-value";
import { XMarkIcon } from "@heroicons/react/24/solid"; import { XMarkIcon } from "@heroicons/react/24/solid";
import clsx from "clsx"; import clsx from "clsx";
import { accuracyToColor } from "@/common/song-utils";
type Badge = { type Badge = {
name: string; name: string;
color?: (
score: ScoreSaberScore,
leaderboard: ScoreSaberLeaderboard,
) => string | undefined;
create: ( create: (
score: ScoreSaberScore, score: ScoreSaberScore,
leaderboard: ScoreSaberLeaderboard, leaderboard: ScoreSaberLeaderboard,
@ -16,6 +21,9 @@ type Badge = {
const badges: Badge[] = [ const badges: Badge[] = [
{ {
name: "PP", name: "PP",
color: () => {
return "bg-pp";
},
create: (score: ScoreSaberScore) => { create: (score: ScoreSaberScore) => {
const pp = score.pp; const pp = score.pp;
if (pp === 0) { if (pp === 0) {
@ -26,6 +34,10 @@ const badges: Badge[] = [
}, },
{ {
name: "Accuracy", name: "Accuracy",
color: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => {
const acc = (score.baseScore / leaderboard.maxScore) * 100;
return accuracyToColor(acc);
},
create: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => { create: (score: ScoreSaberScore, leaderboard: ScoreSaberLeaderboard) => {
const acc = (score.baseScore / leaderboard.maxScore) * 100; const acc = (score.baseScore / leaderboard.maxScore) * 100;
return `${acc.toFixed(2)}%`; return `${acc.toFixed(2)}%`;
@ -78,11 +90,11 @@ export default function ScoreStats({ score, leaderboard }: Props) {
<div className={`grid grid-cols-3 grid-rows-2 gap-1 ml-0 lg:ml-2`}> <div className={`grid grid-cols-3 grid-rows-2 gap-1 ml-0 lg:ml-2`}>
{badges.map((badge, index) => { {badges.map((badge, index) => {
const toRender = badge.create(score, leaderboard); const toRender = badge.create(score, leaderboard);
let color = badge.color?.(score, leaderboard);
if (toRender === undefined) { if (toRender === undefined) {
return <div key={index} />; return <div key={index} />;
} }
return <StatValue key={index} color={color} value={toRender} />;
return <StatValue key={index} value={toRender} />;
})} })}
</div> </div>
); );

@ -1,4 +1,4 @@
import clsx, { ClassValue } from "clsx"; import clsx from "clsx";
type Props = { type Props = {
/** /**
@ -9,7 +9,7 @@ type Props = {
/** /**
* The background color of the stat. * The background color of the stat.
*/ */
color?: ClassValue; color?: string;
/** /**
* The value of the stat. * The value of the stat.
@ -24,6 +24,9 @@ export default function StatValue({ name, color, value }: Props) {
"flex min-w-16 gap-2 h-[28px] p-1 items-center justify-center rounded-md text-sm", "flex min-w-16 gap-2 h-[28px] p-1 items-center justify-center rounded-md text-sm",
color ? color : "bg-accent", color ? color : "bg-accent",
)} )}
style={{
backgroundColor: (!color?.includes("bg") && color) || undefined,
}}
> >
{name && ( {name && (
<> <>

@ -10,7 +10,7 @@ const config: Config = {
theme: { theme: {
extend: { extend: {
colors: { colors: {
pp: "#a147fa", pp: "#606fff",
background: "hsl(var(--background))", background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))", foreground: "hsl(var(--foreground))",
card: { card: {