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()
})
})