import { ScoresaberLeaderboardInfo } from "@/schemas/scoresaber/leaderboard"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberScore } from "@/schemas/scoresaber/score"; import { formatNumber } from "@/utils/numberUtils"; import { getPpGainedFromScore } from "@/utils/scoresaber/scores"; import { scoresaberDifficultyNumberToName, songDifficultyToColor, } from "@/utils/songUtils"; import { formatDate, formatTimeAgo } from "@/utils/timeUtils"; import { CheckIcon, GlobeAsiaAustraliaIcon, StarIcon, XMarkIcon, } from "@heroicons/react/20/solid"; import clsx from "clsx"; import Image from "next/image"; import Link from "next/link"; import HeadsetIcon from "../icons/HeadsetIcon"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/Tooltip"; import ScoreStatLabel from "./ScoreStatLabel"; type ScoreProps = { score: ScoresaberScore; player: ScoresaberPlayer; leaderboard: ScoresaberLeaderboardInfo; ownProfile?: ScoresaberPlayer; }; export default function Score({ score, player, leaderboard, ownProfile, }: ScoreProps) { const isFullCombo = score.missedNotes + score.badCuts === 0; const diffName = scoresaberDifficultyNumberToName( leaderboard.difficulty.difficulty, ); const diffColor = songDifficultyToColor(diffName); const accuracy = ((score.baseScore / leaderboard.maxScore) * 100).toFixed(2); const totalMissedNotes = score.missedNotes + score.badCuts; const weightedPp = formatNumber(getPpGainedFromScore(player.id, score), 2); return (

#{formatNumber(score.rank)}

{formatTimeAgo(score.timeSet)}

Time Submitted

{formatDate(score.timeSet)}

{/* Song Image */}
{leaderboard.songName}
{leaderboard.ranked ? (
{leaderboard.stars.toFixed(2)}
<>

Difficulty

{diffName}

) : (

{diffName}

)}
{/* Song Info */}

{leaderboard.songName}

{leaderboard.songAuthorName}

{leaderboard.levelAuthorName}

{/* Score rank */}

#{formatNumber(score.rank)}

{/* Time Set (Mobile) */}

{formatTimeAgo(score.timeSet)}

Time Submitted

{formatDate(score.timeSet)}

{/* PP */}
{score.pp > 0 && (

Performance Points

{weightedPp !== null &&

Weighted PP: {weightedPp}pp

}

Raw PP: {formatNumber(score.pp, 2)}pp

} /> )} {/* Percentage score */}

Score

Accuracy: {accuracy}%

Raw Score: {formatNumber(score.baseScore)}

} value={ !leaderboard.maxScore ? formatNumber(score.baseScore) : accuracy + "%" } />
{/* Missed Notes */}

Mistakes

{isFullCombo ? (

Full Combo

) : ( <>

Misses: {score.missedNotes}

Bad Cuts: {score.badCuts}

)}
} icon={ isFullCombo ? ( ) : ( ) } value={isFullCombo ? "FC" : formatNumber(totalMissedNotes) + "x"} />
); }