Added more to guild stats sidebar
This commit is contained in:
@@ -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 (
|
||||
<div>
|
||||
<p className="font-bold">Leveling Progress</p>
|
||||
<div className="flex gap-2 items-center mt-2">
|
||||
<p className={textColor}>{Math.floor(level)}</p>
|
||||
<GenericProgress
|
||||
percent={percent}
|
||||
tooltipId="guild-level-progress"
|
||||
tooltipContent={`${formatNumber(guild.exp - currentXp)}/${formatNumber(nextXp - currentXp)} GEXP`}
|
||||
className={bgColor}
|
||||
/>
|
||||
<p className={textColor}>{Math.floor(level) + 1}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function GeneralInfo() {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">{"Level: "}</span>
|
||||
<span>{formatNumber(level)}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Created: "}</span>
|
||||
<span>{formatDate(guild.created)}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Legacy Rank: "}</span>
|
||||
<span>{guild.legacyRanking !== undefined ? formatNumber(guild.legacyRanking) : "None"}</span>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Other() {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">{"Members: "}</span>
|
||||
<span>{guild.members.length}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Publicly Listed: "}</span>
|
||||
<span>{guild.publiclyListed === true ? "Yes" : "No"}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="font-bold">{"Publicly Joinable: "}</span>
|
||||
<span>{guild.joinable === true ? "Yes" : "No"}</span>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function PreferedGames() {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">{"Preferred Games: "}</span>
|
||||
{guild.preferredGames === undefined ? <span>No prefered games</span> : (
|
||||
<span>
|
||||
{guild.preferredGames.map(g => {
|
||||
const game = getGame(g)
|
||||
return game?.name || null
|
||||
}).filter(g => g !== null).sort().join(", ")}
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="mx-auto w-full lg:mx-0 lg:w-1/4 max-w-120 md:max-w-3/10">
|
||||
<CardHeader className="flex justify-center">
|
||||
<CardTitle className={cn("text-4xl", guild.tag && tagColor)}>
|
||||
<CardTitle className={cn("text-4xl", guild.tag && textColor)}>
|
||||
{guild.tag !== undefined ? `[${guild.tag}]` : "No Guild Tag"}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
@@ -22,6 +105,14 @@ export default function Sidebar({ guild }: SidebarProps) {
|
||||
<ReplaceLinks text={guild.description} /> :
|
||||
<p>No guild description.</p>}
|
||||
<Separator className="my-4" />
|
||||
<LevelingProgress />
|
||||
<Separator className="my-4" />
|
||||
<GeneralInfo />
|
||||
<Separator className="my-4" />
|
||||
<Other />
|
||||
<Separator className="my-4" />
|
||||
<PreferedGames />
|
||||
<Separator className="my-4" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
|
||||
17
src/data/hypixel/guild.ts
Normal file
17
src/data/hypixel/guild.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export const EXP = [
|
||||
100000,
|
||||
150000,
|
||||
250000,
|
||||
500000,
|
||||
750000,
|
||||
1000000,
|
||||
1250000,
|
||||
1500000,
|
||||
2000000,
|
||||
2500000,
|
||||
2500000,
|
||||
2500000,
|
||||
2500000,
|
||||
2500000,
|
||||
3000000
|
||||
] as const
|
||||
21
src/lib/hypixel/guild/level.ts
Normal file
21
src/lib/hypixel/guild/level.ts
Normal file
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user