diff --git a/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-components.tsx b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-components.tsx new file mode 100644 index 0000000..54504e2 --- /dev/null +++ b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars-components.tsx @@ -0,0 +1,24 @@ +import { getBedwarsStar, getTextColor } from "@/lib/hypixel/bedwars" +import { getBWLevelForExp } from "@/lib/hypixel/bedwarsLevel" +import { bedwarsLevelColors } from "@/lib/hypixelFormatters" +import Multicolored from "../../_components/Multicolored" + +export function BedwarsLevel({ xp }: { xp: number }) { + const level = getBWLevelForExp(xp) + const color = bedwarsLevelColors(level) + const star = getBedwarsStar(level) + const val = `[${level}${star}]` + + return +} + +export function BedwarsProgress({ level, percent }: { level: number, percent: number }) { + return ( +
+
{level}
+
+
+
{level + 1}
+
+ ) +} diff --git a/src/app/(stats)/player/[ign]/_components/stats/bedewars.tsx b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars.tsx similarity index 67% rename from src/app/(stats)/player/[ign]/_components/stats/bedewars.tsx rename to src/app/(stats)/player/[ign]/_stats/bedwars/bedwars.tsx index 605cd5c..4f87713 100644 --- a/src/app/(stats)/player/[ign]/_components/stats/bedewars.tsx +++ b/src/app/(stats)/player/[ign]/_stats/bedwars/bedwars.tsx @@ -2,15 +2,15 @@ import { Card, CardContent } from "@/components/ui/card" import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible" -import { getBedwarsStar } from "@/lib/hypixel/bedwars" -import { getBWLevelForExp } from "@/lib/hypixel/bedwarsLevel" -import { bedwarsLevelColors } from "@/lib/hypixelFormatters" +import { getBedwarsStar, getPrestigeName, getTextColor } from "@/lib/hypixel/bedwars" +import { getBWLevelForExp, getTotalExpForLevel } from "@/lib/hypixel/bedwarsLevel" +import { getProgress } from "@/lib/hypixel/general" import { Player } from "@/lib/schema/player" import { Separator } from "@radix-ui/react-separator" import { ChevronDown, ChevronUp, Menu } from "lucide-react" import { useEffect, useRef, useState } from "react" -import CollapsedStats from "../CollapsedStats" -import Multicolored from "../Multicolored" +import CollapsedStats from "../../_components/CollapsedStats" +import { BedwarsLevel, BedwarsProgress } from "./bedwars-components" export default function BedwarsStats({ stats }: { stats: Player["player"]["stats"]["Bedwars"] }) { const ref = useRef(null) @@ -42,6 +42,13 @@ export default function BedwarsStats({ stats }: { stats: Player["player"]["stats const fkd = (stats.final_kills_bedwars / stats.final_deaths_bedwars).toFixed(2) const wl = (stats.wins_bedwars / stats.losses_bedwars).toFixed(2) const bbl = (stats.beds_broken_bedwars / stats.beds_lost_bedwars).toFixed(2) + const level = getBWLevelForExp(stats.Experience) + + const percent = getProgress( + getTotalExpForLevel(level), + stats.Experience, + getTotalExpForLevel(level + 1) + ) return ( @@ -88,18 +95,32 @@ export default function BedwarsStats({ stats }: { stats: Player["player"]["stats + +
+
+
+

+ {"Level: "} + {`${level}.${percent.toFixed(0)}`} +

+

+ {"Prestige: "} + + {`${getPrestigeName(level)} ${getBedwarsStar(level)}`} + +

+

+ {"Tokens: "} + {} +

+
+
+
+
+
) } - -function BedwarsLevel({ xp }: { xp: number }) { - const level = getBWLevelForExp(xp) - const color = bedwarsLevelColors(level) - const star = getBedwarsStar(level) - const val = `[${level}${star}]` - - return -} diff --git a/src/app/(stats)/player/[ign]/page.tsx b/src/app/(stats)/player/[ign]/page.tsx index b925fc2..e7d6de2 100644 --- a/src/app/(stats)/player/[ign]/page.tsx +++ b/src/app/(stats)/player/[ign]/page.tsx @@ -4,7 +4,7 @@ import { getUuid } from "@/lib/hypixel/api/mojang" import { getPlayer } from "@/lib/hypixel/api/player" import { getExactLevel } from "@/lib/hypixel/level" import Sidebar from "./_components/Sidebar" -import BedwarsStats from "./_components/stats/bedewars" +import BedwarsStats from "./_stats/bedwars/bedwars" export default async function PlayerPage({ params diff --git a/src/app/globals.css b/src/app/globals.css index 95c7ed9..220d365 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -4,138 +4,137 @@ @custom-variant dark (&:is(.dark *)); @theme inline { - --color-mc-black: #000000; - --color-mc-dark-blue: #0000AA; - --color-mc-dark-green: #00AA00; - --color-mc-dark-aqua: #00AAAA; - --color-mc-dark-red: #AA0000; - --color-mc-dark-purple: #AA00AA; - --color-mc-gold: #FFAA00; - --color-mc-gray: #AAAAAA; - --color-mc-light-gray: #C6C6C6; - --color-mc-dark-gray: #555555; - --color-mc-blue: #5555FF; - --color-mc-green: #55FF55; - --color-mc-aqua: #55FFFF; - --color-mc-red: #FF5555; - --color-mc-light-purple: #FF55FF; - --color-mc-yellow: #FFFF55; - --color-mc-white: #FFFFFF; + --color-mc-black: #000000; + --color-mc-dark-blue: #0000AA; + --color-mc-dark-green: #00AA00; + --color-mc-dark-aqua: #00AAAA; + --color-mc-dark-red: #AA0000; + --color-mc-dark-purple: #AA00AA; + --color-mc-gold: #FFAA00; + --color-mc-gray: #AAAAAA; + --color-mc-dark-gray: #555555; + --color-mc-blue: #5555FF; + --color-mc-green: #55FF55; + --color-mc-aqua: #55FFFF; + --color-mc-red: #FF5555; + --color-mc-light-purple: #FF55FF; + --color-mc-yellow: #FFFF55; + --color-mc-white: #FFFFFF; } @theme inline { - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-card: var(--card); - --color-card-foreground: var(--card-foreground); - --color-popover: var(--popover); - --color-popover-foreground: var(--popover-foreground); - --color-primary: var(--primary); - --color-primary-foreground: var(--primary-foreground); - --color-secondary: var(--secondary); - --color-secondary-foreground: var(--secondary-foreground); - --color-muted: var(--muted); - --color-muted-foreground: var(--muted-foreground); - --color-accent: var(--accent); - --color-accent-foreground: var(--accent-foreground); - --color-destructive: var(--destructive); - --color-border: var(--border); - --color-input: var(--input); - --color-ring: var(--ring); - --color-chart-1: var(--chart-1); - --color-chart-2: var(--chart-2); - --color-chart-3: var(--chart-3); - --color-chart-4: var(--chart-4); - --color-chart-5: var(--chart-5); - --color-sidebar: var(--sidebar); - --color-sidebar-foreground: var(--sidebar-foreground); - --color-sidebar-primary: var(--sidebar-primary); - --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); - --color-sidebar-accent: var(--sidebar-accent); - --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); - --color-sidebar-border: var(--sidebar-border); - --color-sidebar-ring: var(--sidebar-ring); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); } :root { - --radius: 0.625rem; - --background: oklch(1 0 0); - --foreground: oklch(0.145 0 0); - --card: oklch(1 0 0); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.145 0 0); - --primary: oklch(0.205 0 0); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.97 0 0); - --secondary-foreground: oklch(0.205 0 0); - --muted: oklch(0.97 0 0); - --muted-foreground: oklch(0.556 0 0); - --accent: oklch(0.97 0 0); - --accent-foreground: oklch(0.205 0 0); - --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.205 0 0); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); } .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.205 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.205 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.922 0 0); - --primary-foreground: oklch(0.205 0 0); - --secondary: oklch(0.269 0 0); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.269 0 0); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.556 0 0); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.556 0 0); + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); } @layer base { - * { - @apply border-border outline-ring/50; - } + * { + @apply border-border outline-ring/50; + } - body { - @apply bg-background text-foreground; - } -} \ No newline at end of file + body { + @apply bg-background text-foreground; + } +} diff --git a/src/data/colors.ts b/src/data/colors.ts index 67b4502..c391693 100644 --- a/src/data/colors.ts +++ b/src/data/colors.ts @@ -6,7 +6,7 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo return type === "text" ? "text-mc-red" : "bg-mc-red" case "GOLD": return type === "text" ? "text-mc-gold" : "bg-mc-gold" - case "LIME": + case "GREEN": return type === "text" ? "text-mc-green" : "bg-mc-green" case "YELLOW": return type === "text" ? "text-mc-yellow" : "bg-mc-yellow" @@ -16,12 +16,12 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo return type === "text" ? "text-mc-white" : "bg-mc-white" case "BLUE": return type === "text" ? "text-mc-blue" : "bg-mc-blue" - case "GREEN": - return type === "text" ? "text-mc-green" : "bg-mc-green" - case "DARK_RED": - return type === "text" ? "text-mc-dark-red" : "bg-mc-dark-red" case "DARK_GREEN": return type === "text" ? "text-mc-dark-green" : "bg-mc-dark-green" + case "DARK_RED": + return type === "text" ? "text-mc-dark-red" : "bg-mc-dark-red" + case "DARK_AQUA": + return type === "text" ? "text-mc-dark-aqua" : "bg-mc-dark-red" case "DARK_PURPLE": return type === "text" ? "text-mc-dark-purple" : "bg-mc-dark-purple" case "DARK_GRAY": @@ -30,6 +30,8 @@ export function getColor(color?: string, type: "text" | "bg" = "text", defaultCo return type === "text" ? "text-mc-black" : "bg-mc-black" case "DARK_BLUE": return type === "text" ? "text-mc-dark-blue" : "bg-mc-dark-blue" + case "GRAY": + return type === "text" ? "text-mc-gray" : "bg-mc-gray" default: return type === "text" ? `text-mc-${defaultColor}` : `bg-mc-${defaultColor}` } diff --git a/src/data/hypixel/bedwars.ts b/src/data/hypixel/bedwars.ts index 95083b1..f3ab55b 100644 --- a/src/data/hypixel/bedwars.ts +++ b/src/data/hypixel/bedwars.ts @@ -4,10 +4,10 @@ export const PRESTIGES = [ { level: 100, colormap: "f", color: "white", name: "Iron" }, { level: 200, colormap: "6", color: "gold", name: "Gold" }, { level: 300, colormap: "b", color: "aqua", name: "Diamond" }, - { level: 400, colormap: "2", color: "darkgreen", name: "Emerald" }, - { level: 500, colormap: "3", color: "darkaqua", name: "Sapphire" }, - { level: 600, colormap: "4", color: "darkred", name: "Ruby" }, - { level: 700, colormap: "d", color: "pink", name: "Crystal" }, + { level: 400, colormap: "2", color: "dark-green", name: "Emerald" }, + { level: 500, colormap: "3", color: "dark-aqua", name: "Sapphire" }, + { level: 600, colormap: "4", color: "dark-red", name: "Ruby" }, + { level: 700, colormap: "d", color: "light-purple", name: "Crystal" }, { level: 800, colormap: "9", color: "blue", name: "Opal" }, { level: 900, colormap: "5", color: "purple", name: "Amethyst" }, { level: 1000, colormap: "c6eabd5", color: "rainbow", name: "Rainbow" }, @@ -15,9 +15,9 @@ export const PRESTIGES = [ { level: 1200, colormap: "7eeee67", color: "yellow", name: "Gold Prime" }, { level: 1300, colormap: "7bbbb37", color: "aqua", name: "Diamond Prime" }, { level: 1400, colormap: "7aaaa27", color: "green", name: "Emerald Prime" }, - { level: 1500, colormap: "7333397", color: "darkaqua", name: "Sapphire Prime" }, + { level: 1500, colormap: "7333397", color: "dark-aqua", name: "Sapphire Prime" }, { level: 1600, colormap: "7cccc47", color: "red", name: "Ruby Prime" }, - { level: 1700, colormap: "7dddd57", color: "pink", name: "Crystal Prime" }, + { level: 1700, colormap: "7dddd57", color: "light-purple", name: "Crystal Prime" }, { level: 1800, colormap: "7999917", color: "blue", name: "Opal Prime" }, { level: 1900, colormap: "7555587", color: "purple", name: "Amethyst Prime" }, { level: 2000, colormap: "87ff778", color: "white", name: "Mirror" }, @@ -26,31 +26,31 @@ export const PRESTIGES = [ { level: 2300, colormap: "55dd6ee", color: "purple", name: "Dusk" }, { level: 2400, colormap: "bbff778", color: "white", name: "Air" }, { level: 2500, colormap: "ffaa222", color: "green", name: "Wind" }, - { level: 2600, colormap: "44ccdd5", color: "darkred", name: "Nebula" }, + { level: 2600, colormap: "44ccdd5", color: "dark-red", name: "Nebula" }, { level: 2700, colormap: "eeff777", color: "yellow", name: "Thunder" }, - { level: 2800, colormap: "aa2266e", color: "darkgreen", name: "Earth" }, + { level: 2800, colormap: "aa2266e", color: "dark-green", name: "Earth" }, { level: 2900, colormap: "bb33991", color: "blue", name: "Water" }, { level: 3000, colormap: "ee66cc4", color: "red", name: "Fire" }, { level: 3100, colormap: "993366e", color: "blue", name: "Sunshine" }, - { level: 3200, colormap: "c4774cc", color: "darkred", name: "Eclipse" }, + { level: 3200, colormap: "c4774cc", color: "dark-red", name: "Eclipse" }, { level: 3300, colormap: "999dcc4", color: "blue", name: "Gamma" }, { level: 3400, colormap: "2add552", color: "green", name: "Majestic" }, { level: 3500, colormap: "cc442aa", color: "red", name: "Andesine" }, { level: 3600, colormap: "aaab991", color: "green", name: "Marine" }, - { level: 3700, colormap: "44ccb33", color: "darkred", name: "Element" }, - { level: 3800, colormap: "11955d1", color: "darkblue", name: "Galaxy" }, + { level: 3700, colormap: "44ccb33", color: "dark-red", name: "Element" }, + { level: 3800, colormap: "11955d1", color: "dark-blue", name: "Galaxy" }, { level: 3900, colormap: "ccaa399", color: "red", name: "Atomic" }, { level: 4000, colormap: "55cc66e", color: "purple", name: "Sunset" }, { level: 4100, colormap: "ee6cdd5", color: "yellow", name: "Time" }, { level: 4200, colormap: "193bf77", color: "blue", name: "Winter" }, { level: 4300, colormap: "0588550", color: "purple", name: "Obsidian" }, - { level: 4400, colormap: "22ae65d", color: "darkgreen", name: "Spring" }, + { level: 4400, colormap: "22ae65d", color: "dark-green", name: "Spring" }, { level: 4500, colormap: "ffbb333", color: "white", name: "Ice" }, { level: 4600, colormap: "3bee6d5", color: "aqua", name: "Summer" }, - { level: 4700, colormap: "f4cc919", color: "darkred", name: "Spinel" }, + { level: 4700, colormap: "f4cc919", color: "dark-red", name: "Spinel" }, { level: 4800, colormap: "55c6eb3", color: "purple", name: "Autumn" }, { level: 4900, colormap: "2affaa2", color: "green", name: "Mystic" }, - { level: 5000, colormap: "4459910", color: "darkred", name: "Eternal" } + { level: 5000, colormap: "4459910", color: "dark-red", name: "Eternal" } ] export const PRESTIGE_ICONS = [ { level: 0, symbol: "✫" }, diff --git a/src/lib/formatters.ts b/src/lib/formatters.ts index a29be37..d424801 100644 --- a/src/lib/formatters.ts +++ b/src/lib/formatters.ts @@ -1,20 +1,20 @@ const numberFormatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 2, - minimumFractionDigits: 0, -}); + minimumFractionDigits: 0 +}) const dateFormatter = new Intl.DateTimeFormat(undefined, { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - hour12: false, -}); + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + hour12: false +}) export function formatNumber(num: number): string { - return numberFormatter.format(num); + return numberFormatter.format(num) } export function formatDate(timestamp: number): string { - return dateFormatter.format(new Date(timestamp)); -} \ No newline at end of file + return dateFormatter.format(new Date(timestamp)) +} diff --git a/src/lib/hypixel/api/player.ts b/src/lib/hypixel/api/player.ts index 436b706..36b5abf 100644 --- a/src/lib/hypixel/api/player.ts +++ b/src/lib/hypixel/api/player.ts @@ -17,4 +17,5 @@ export async function getPlayer(uuid: string) { if (!success) return null return data.player -} \ No newline at end of file +} + diff --git a/src/lib/hypixel/bedwars.ts b/src/lib/hypixel/bedwars.ts index ac7fcf7..8e993bf 100644 --- a/src/lib/hypixel/bedwars.ts +++ b/src/lib/hypixel/bedwars.ts @@ -1,4 +1,5 @@ -import { PRESTIGE_ICONS } from "@/data/hypixel/bedwars" +import { PRESTIGE_ICONS, PRESTIGES } from "@/data/hypixel/bedwars" +import { floorLevel } from "./formatters" export function getBedwarsStar(level: number) { if (level < 1100) { @@ -15,3 +16,23 @@ export function getBedwarsStar(level: number) { return PRESTIGE_ICONS[3].symbol } + +export function getTextColor(level: number) { + const floored = floorLevel(level, 100) + + if (level > 5000) { + return PRESTIGES[PRESTIGES.length - 1].color + } + + return PRESTIGES.find(l => l.level === floored)!.color +} + +export function getPrestigeName(level: number) { + const floored = floorLevel(level, 100) + + if (level > 5000) { + return PRESTIGES[PRESTIGES.length - 1].name + } + + return PRESTIGES.find(p => p.level === floored)!.name +} diff --git a/src/lib/hypixel/bedwarsLevel.ts b/src/lib/hypixel/bedwarsLevel.ts index a4464e7..615b1d0 100644 --- a/src/lib/hypixel/bedwarsLevel.ts +++ b/src/lib/hypixel/bedwarsLevel.ts @@ -7,7 +7,7 @@ const XP_PER_PRESTIGE = 96 * 5000 + EASY_LEVELS_XP const LEVELS_PER_PRESTIGE = 100 const HIGHEST_PRESTIGE = 10 -export function getBWLevel(level: number) { +function getBWLevel(level: number) { if (level > HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE) { return level - HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE } @@ -15,7 +15,7 @@ export function getBWLevel(level: number) { return level % LEVELS_PER_PRESTIGE } -export function getBWExpForLevel(level: number) { +function getBWExpForLevel(level: number) { if (level === 0) return 0 const respectedLevel = getBWLevel(level) @@ -53,3 +53,17 @@ export function getBWLevelForExp(exp: number) { } return level + Math.floor(expWithoutPrestiges / 5000) } + +export function getTotalExpForLevel(level: number): number { + if (level === 0) return 0 + + const prestiges = Math.floor(level / LEVELS_PER_PRESTIGE) + let totalExp = prestiges * XP_PER_PRESTIGE + const remainingLevels = level % LEVELS_PER_PRESTIGE + + for (let i = 1; i <= remainingLevels; i += 1) { + totalExp += getBWExpForLevel(i) + } + + return totalExp +} diff --git a/src/lib/hypixel/general.ts b/src/lib/hypixel/general.ts new file mode 100644 index 0000000..959c4ef --- /dev/null +++ b/src/lib/hypixel/general.ts @@ -0,0 +1,7 @@ +export function getProgress(min: number, mid: number, max: number) { + if (max === min) return 100 + const diff = max - min + const progress = mid - min + + return progress / diff * 100 +} diff --git a/src/lib/schema/player.ts b/src/lib/schema/player.ts index 34af9eb..0c6a9a5 100644 --- a/src/lib/schema/player.ts +++ b/src/lib/schema/player.ts @@ -2,18 +2,18 @@ import z from "zod" export const playerSchema = z.looseObject({ player: z.looseObject({ - displayname: z.string(), - uuid: z.string(), - newPackageRank: z.literal("VIP").or(z.literal("VIP_PLUS").or(z.literal("MVP")).or(z.literal("MVP_PLUS"))).optional(), + displayname: z.string().optional(), + uuid: z.string().optional(), + newPackageRank: z.string().optional(), monthlyPackageRank: z.string().optional(), rankPlusColor: z.string().optional(), - monthlyRankColor: z.literal("GOLD").or(z.literal("AQUA")).optional(), - networkExp: z.number(), - karma: z.number(), - achievementPoints: z.number().optional(), + monthlyRankColor: z.string().optional(), + networkExp: z.number().default(0), + karma: z.number().default(0), + achievementPoints: z.number().default(0), stats: z.looseObject({ Bedwars: z.looseObject({ - Experience: z.number(), + Experience: z.number().default(0), winstreak: z.number().optional(), kills_bedwars: z.number().default(0), deaths_bedwars: z.number().default(0), @@ -33,11 +33,11 @@ export const playerSchema = z.looseObject({ time: z.number() }).optional() ).optional() - }) - ), + }).optional() + ).optional(), challenges: z.looseObject({ all_time: z.record(z.string(), z.number()) - }), + }).optional(), lastClaimedReward: z.number().optional(), rewardHighScore: z.number().optional(), rewardStreak: z.number().optional(), @@ -55,8 +55,8 @@ export const playerSchema = z.looseObject({ HYPIXEL: z.string().optional(), TWITTER: z.string().optional(), YOUTUBE: z.string().optional() - }) - }) + }).optional() + }).optional() }) }) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index bd0c391..03aaa4b 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,6 @@ -import { clsx, type ClassValue } from "clsx" +import { type ClassValue, clsx } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) + return twMerge(clsx(inputs)) }