Finished smash heros card header

This commit is contained in:
2025-09-18 10:19:07 +02:00
parent 28a63b43b0
commit c6a4fe2a55
7 changed files with 142 additions and 4 deletions

View File

@@ -2,7 +2,7 @@ import ClearCookiesButton from "@/components/clear-cookies"
export default function SettingsPage() {
return (
<div className="p-8 space-y-4">
<div className="px-8 pb-8 space-y-4 pt-[calc(var(--spacing-header)+2rem)]">
<div>
<h2 className="text-2xl font-bold">Cookies</h2>
<p>The site stores cookies to save prefrences. If you wish to delete these cookies use the bottom bellow.</p>

View File

@@ -22,6 +22,7 @@ import MegaWallsStats from "./_stats/megawalls/megawalls"
import MurderMysteryStats from "./_stats/murder-mystery/murder-mystery"
import PitStats from "./_stats/pit/pit"
import SkyWarsStats from "./_stats/skywars/skywars"
import SmashHerosStats from "./_stats/smashheros/smashheros"
import SpeedUHCStats from "./_stats/speeduhc/speeduhc"
import TNTGamesStats from "./_stats/tnt-games/tnt-games"
import UHCStats from "./_stats/uhc/uhc"
@@ -94,7 +95,8 @@ export function PlayerStats(
"woolgames": <WoolGamesStats stats={stats.WoolGames} />,
"blitz": <BlitzStats stats={stats.Blitz} />,
"arcade": <ArcadeStats stats={stats.Arcade} />,
"speeduhc": <SpeedUHCStats stats={stats.SpeedUHC} uhcCoins={stats.UHC?.coins} />
"speeduhc": <SpeedUHCStats stats={stats.SpeedUHC} uhcCoins={stats.UHC?.coins} />,
"smashheros": <SmashHerosStats stats={stats.SmashHeros} />
} as const
const defaultOrder = Object.keys(statsComponents)

View File

@@ -0,0 +1,51 @@
import { Separator } from "@/components/ui/separator"
import { formatNumber } from "@/lib/formatters"
import { devide } from "@/lib/hypixel/general"
import { getSmashHerosDifficultyColor, getSmashHerosMostPlayedHero } from "@/lib/hypixel/smashhero/general"
import { NonNullStats } from "@/lib/schema/player"
import GeneralStats from "../GeneralStats"
export default function SmashHerosStats({ stats }: { stats: NonNullStats["SmashHeros"] }) {
if (!stats) return null
const kd = formatNumber(devide(stats.kills, stats.deaths))
const wl = formatNumber(devide(stats.wins, stats.losses))
const mostPlayed = getSmashHerosMostPlayedHero(stats)
const diffiultyColor = getSmashHerosDifficultyColor(mostPlayed?.difficulty ?? 0)
return (
<GeneralStats
id="smashheros"
title="Smash Heros"
collapsedStats={[
{
title: <p>Main</p>,
stat: <p className={`text-mc-${diffiultyColor}`}>{mostPlayed !== null ? mostPlayed.name : "Unknown"}</p>
},
{
title: <p>Level</p>,
stat: (
<p>
<span className="text-mc-aqua">{stats.smashLevel}</span>
<span className="text-mc-gold">{"\u2736"}</span>
</p>
)
},
{
title: <p>KD</p>,
stat: <p>{kd}</p>
},
{
title: <p>Wins</p>,
stat: <p>{formatNumber(stats.wins)}</p>
},
{
title: <p>WL</p>,
stat: <p>{wl}</p>
}
]}
>
<Separator className="my-4" />
</GeneralStats>
)
}

View File

@@ -0,0 +1,26 @@
export const MODES = [
{ id: "normal", name: "1v1v1v1" },
{ id: "2v2", name: "2v2" },
{ id: "teams", name: "2v2v2" },
{ id: "", name: "Overall" }
] as const
export const HEROES = [
{ id: "BOTMUN", name: "Botmon", difficulty: 1 },
{ id: "THE_BULK", name: "Bulk", difficulty: 2 },
{ id: "CAKE_MONSTER", name: "Cake Monster", difficulty: 2 },
{ id: "FROSTY", name: "Cryomancer", difficulty: 3 },
{ id: "GENERAL_CLUCK", name: "General Cluck", difficulty: 1 },
{ id: "GREEN_HOOD", name: "Green Hood", difficulty: 4 },
{ id: "GOKU", name: "Karakot", difficulty: 3 },
{ id: "MARAUDER", name: "Marauder", difficulty: 2 },
{ id: "PUG", name: "Pug", difficulty: 2 },
{ id: "SANIC", name: "Sanic", difficulty: 2 },
{ id: "SERGEANT_SHIELD", name: "Sgt. Shield", difficulty: 3 },
{ id: "SHOOP_DA_WHOOP", name: "Shoop", difficulty: 3 },
{ id: "SKULLFIRE", name: "Skullfire", difficulty: 3 },
{ id: "SPODERMAN", name: "Spooderman", difficulty: 4 },
{ id: "TINMAN", name: "Tinman", difficulty: 1 },
{ id: "DUSK_CRAWLER", name: "Void Crawler", difficulty: 2 }
] as const
export const DIFFICULTY = ["green", "yellow", "red", "dark-red"] as const
export const PRESTIGECOLORS = ["white", "green", "blue", "dark-purple", "gold"] as const

View File

@@ -0,0 +1,25 @@
import { DIFFICULTY, HEROES } from "@/data/hypixel/smashheros"
import { NonNullStats } from "@/lib/schema/player"
export function getSmashHerosDifficultyColor(difficulty: number) {
if (difficulty < 1) return DIFFICULTY.at(0)!
if (difficulty > DIFFICULTY.length) return DIFFICULTY.at(-1)!
return DIFFICULTY.at(difficulty - 1)!
}
export function getSmashHerosMostPlayedHero(stats: NonNullable<NonNullStats["SmashHeros"]>) {
if (!stats.class_stats) return null
let maxGames = 0
let mostPlayedHero: typeof HEROES[number] | null = null
for (const hero of HEROES) {
const games = stats.class_stats[hero.id]?.games ?? 0
if (games > maxGames) {
maxGames = games
mostPlayedHero = hero
}
}
return mostPlayedHero
}

View File

@@ -9,6 +9,7 @@ import { megawallsStats } from "./stats/megawalls"
import { murderMysteryStatsSchema } from "./stats/murder-mystery"
import { pitStats } from "./stats/pit"
import { skywarsStatsSchema } from "./stats/skywars"
import { smashHerosStats } from "./stats/smashheros"
import { speedUhcStatsSchema } from "./stats/speeduhc"
import { tntGamesStatsSchema } from "./stats/tnt-games"
import { uhcSchema } from "./stats/uhc"
@@ -40,12 +41,14 @@ export const playerSchema = z.looseObject({
WoolGames: woolGamesStatsSchema.optional(),
HungerGames: blitzStatsSchema.optional(),
Arcade: arcadeStatsSchema.optional(),
SpeedUHC: speedUhcStatsSchema.optional()
}).transform(({ Walls3, MCGO, HungerGames, ...rest }) => {
SpeedUHC: speedUhcStatsSchema.optional(),
SuperSmash: smashHerosStats.optional()
}).transform(({ Walls3, MCGO, HungerGames, SuperSmash, ...rest }) => {
return {
MegaWalls: Walls3,
CopsAndCrims: MCGO,
Blitz: HungerGames,
SmashHeros: SuperSmash,
...rest
}
}).optional(),

View File

@@ -0,0 +1,31 @@
import z from "zod"
const classStats = z.object({
games: z.number().default(0)
}).optional()
export const smashHerosStats = z.object({
kills: z.number().default(0),
deaths: z.number().default(0),
wins: z.number().default(0),
losses: z.number().default(0),
smashLevel: z.number().default(0),
class_stats: z.object({
BOTMUN: classStats,
THE_BULK: classStats,
CAKE_MONSTER: classStats,
FROSTY: classStats,
GENERAL_CLUCK: classStats,
GREEN_HOOD: classStats,
GOKU: classStats,
MARAUDER: classStats,
PUG: classStats,
SANIC: classStats,
SERGEANT_SHIELD: classStats,
SHOOP_DA_WHOOP: classStats,
SKULLFIRE: classStats,
SPODERMAN: classStats,
TINMAN: classStats,
DUSK_CRAWLER: classStats
}).optional()
})