Updated code

This commit is contained in:
2025-10-29 17:26:20 +01:00
parent 857ac578dc
commit b713008819
7 changed files with 76 additions and 71 deletions

View File

@@ -7,10 +7,11 @@ import { formatDate, formatNumber } from "@/lib/formatters"
import { head } from "@/lib/hypixel/general"
import { Guild } from "@/lib/schema/guild"
import { playerForGuildSchema } from "@/lib/schema/player"
import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query"
import { ApiResponse } from "@/types"
import { useQueries } from "@tanstack/react-query"
import Image from "next/image"
import Link from "next/link"
import { useCallback, useEffect, useRef, useState } from "react"
import { useEffect, useRef } from "react"
import { toast } from "sonner"
import z from "zod"
@@ -21,68 +22,27 @@ type MemberWithPlayer = Guild["guild"]["members"][number] & {
error?: boolean
}
const queryClient = new QueryClient()
export function GuildMembers({ members, ranks }: { members: Guild["guild"]["members"], ranks: Guild["guild"]["ranks"] }) {
return (
<QueryClientProvider client={queryClient}>
<GuildMembersInternal members={members} ranks={ranks} />
</QueryClientProvider>
)
}
function useMemberData(uuid: string) {
return useQuery({
queryKey: ["guildMember", uuid],
queryFn: async () => {
const response = await fetch(`/api/guildmembers?uuid=${uuid}`)
const data = await response.json()
if (data.error) {
throw new Error(data.message || "Failed to fetch member data")
}
return data.player as PlayerForGuild["player"]
},
staleTime: 1000 * 60 * 60 * 24,
gcTime: 1000 * 60 * 60,
retry: 3,
retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)
})
}
function MemberRow({ member, onLoad }: { member: Guild["guild"]["members"][number], onLoad: () => void }) {
const { data: player, isLoading, isError } = useMemberData(member.uuid)
useEffect(() => {
if (!isLoading && (player || isError)) {
onLoad()
}
}, [isLoading, player, isError, onLoad])
if (isLoading || (!player && !isError)) return null
if (isError || !player) return null
const memberWithPlayer: MemberWithPlayer = {
...member,
player,
loading: isLoading,
error: isError
}
return <MemberCard member={memberWithPlayer} />
}
function GuildMembersInternal({ members, ranks }: { members: Guild["guild"]["members"], ranks: Guild["guild"]["ranks"] }) {
const [loadedCount, setLoadedCount] = useState(0)
const hasShownToast = useRef(false)
const totalMembers = members.length
const TOAST_ID = "guild.members.progress"
const handleMemberLoad = useCallback(() => {
setLoadedCount(prev => prev + 1)
}, [])
const memberQueries = useQueries({
queries: members.map(member => ({
queryKey: ["guildMember", member.uuid],
queryFn: async () => {
const response = await fetch(`/api/guildmembers?uuid=${member.uuid}`)
const data = await response.json() as ApiResponse<PlayerForGuild["player"]>
if (data.error) {
throw new Error(data.message)
}
return data.player
},
staleTime: 1000 * 60 * 60 * 24
}))
})
const loadedCount = memberQueries.filter(query => !query.isLoading && (query.data || query.isError)).length
const sortedMembers = [...members].sort((a, b) => {
if (a.rank === "Guild Master" && b.rank !== "Guild Master") return -1
@@ -139,13 +99,21 @@ function GuildMembersInternal({ members, ranks }: { members: Guild["guild"]["mem
</TableRow>
</TableHeader>
<TableBody className="space-y-4">
{sortedMembers.map(member => (
<MemberRow
key={member.uuid}
member={member}
onLoad={handleMemberLoad}
/>
))}
{sortedMembers.map((member) => {
const query = memberQueries[members.findIndex(m => m.uuid === member.uuid)]
if (query.isLoading || (!query.data && !query.isError)) return null
if (query.isError || !query.data) return null
const memberWithPlayer: MemberWithPlayer = {
...member,
player: query.data,
loading: query.isLoading,
error: query.isError
}
return <MemberCard key={member.uuid} member={memberWithPlayer} />
})}
</TableBody>
</Table>
</CardContent>