diff --git a/src/app/(stats)/guild/[value]/_components/sidebar.tsx b/src/app/(stats)/guild/[value]/_components/sidebar.tsx index cce1fcc..133c5ae 100644 --- a/src/app/(stats)/guild/[value]/_components/sidebar.tsx +++ b/src/app/(stats)/guild/[value]/_components/sidebar.tsx @@ -1,19 +1,102 @@ +import { GenericProgress } from "@/app/(stats)/player/[ign]/_components/generic-progress" import { ReplaceLinks } from "@/components/link-replace" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Separator } from "@/components/ui/separator" import { getColor } from "@/lib/colors" +import { formatDate, formatNumber } from "@/lib/formatters" +import { getGame } from "@/lib/hypixel/general/status" +import { getGuildExp, getGuildLevel } from "@/lib/hypixel/guild/level" import { Guild } from "@/lib/schema/guild" import { cn } from "@/lib/utils" type SidebarProps = { guild: Guild["guild"] } export default function Sidebar({ guild }: SidebarProps) { - const tagColor = getColor(guild.tagColor, "text", "gray") + const textColor = getColor(guild.tagColor, "text", "gray") + const bgColor = getColor(guild.tagColor, "bg", "gray") + const level = getGuildLevel(guild.exp) + + function LevelingProgress() { + const percent = (level - Math.floor(level)) * 100 + const currentXp = getGuildExp(Math.floor(level)) + const nextXp = getGuildExp(Math.floor(level) + 1) + return ( +
+

Leveling Progress

+
+

{Math.floor(level)}

+ +

{Math.floor(level) + 1}

+
+
+ ) + } + + function GeneralInfo() { + return ( +
+

+ {"Level: "} + {formatNumber(level)} +

+

+ {"Created: "} + {formatDate(guild.created)} +

+

+ {"Legacy Rank: "} + {guild.legacyRanking !== undefined ? formatNumber(guild.legacyRanking) : "None"} +

+
+ ) + } + + function Other() { + return ( +
+

+ {"Members: "} + {guild.members.length} +

+

+ {"Publicly Listed: "} + {guild.publiclyListed === true ? "Yes" : "No"} +

+

+ {"Publicly Joinable: "} + {guild.joinable === true ? "Yes" : "No"} +

+
+ ) + } + + function PreferedGames() { + return ( +
+

+ {"Preferred Games: "} + {guild.preferredGames === undefined ? No prefered games : ( + + {guild.preferredGames.map(g => { + const game = getGame(g) + return game?.name || null + }).filter(g => g !== null).sort().join(", ")} + + )} +

+
+ ) + } return ( - + {guild.tag !== undefined ? `[${guild.tag}]` : "No Guild Tag"} @@ -22,6 +105,14 @@ export default function Sidebar({ guild }: SidebarProps) { :

No guild description.

} + + + + + + + +
) diff --git a/src/data/hypixel/guild.ts b/src/data/hypixel/guild.ts new file mode 100644 index 0000000..d23987c --- /dev/null +++ b/src/data/hypixel/guild.ts @@ -0,0 +1,17 @@ +export const EXP = [ + 100000, + 150000, + 250000, + 500000, + 750000, + 1000000, + 1250000, + 1500000, + 2000000, + 2500000, + 2500000, + 2500000, + 2500000, + 2500000, + 3000000 +] as const diff --git a/src/lib/hypixel/guild/level.ts b/src/lib/hypixel/guild/level.ts new file mode 100644 index 0000000..c70c77f --- /dev/null +++ b/src/lib/hypixel/guild/level.ts @@ -0,0 +1,21 @@ +import { EXP } from "@/data/hypixel/guild" + +export function getGuildLevel(xp: number) { + let xpRemaining = xp + let level = 0 + let xpToLevelUp = EXP[level] + while (xpRemaining >= xpToLevelUp) { + xpRemaining -= xpToLevelUp + level++ + xpToLevelUp = EXP[level > 14 ? 14 : level] + } + return level + xpRemaining / xpToLevelUp +} + +export function getGuildExp(lvl: number) { + let xp = 0 + for (let i = 0; i < lvl; i++) { + xp += EXP[i > 14 ? 14 : i] + } + return xp +} diff --git a/src/lib/schema/guild.ts b/src/lib/schema/guild.ts index 2493441..81d03dc 100644 --- a/src/lib/schema/guild.ts +++ b/src/lib/schema/guild.ts @@ -6,6 +6,9 @@ export const guildSchema = z.object({ name: z.string().min(1), tag: z.string().optional(), tagColor: z.string().optional(), + exp: z.number().default(0), + created: z.number(), + legacyRanking: z.number().optional(), members: z.array(z.object({ uuid: z.string(), rank: z.string(), @@ -20,7 +23,10 @@ export const guildSchema = z.object({ created: z.number(), priority: z.number() })).optional(), - description: z.string().optional() + description: z.string().optional(), + joinable: z.boolean().default(false), + publiclyListed: z.boolean().default(false), + preferredGames: z.array(z.string()).optional() }) })