import { useCallback, useEffect, useState } from "react"; import { ActivityIndicator, ScrollView, StyleSheet, Text, View, } from "react-native"; import Screen from "../../layout/Screen"; import { Button, ButtonTray } from "../../UI/Button"; import Card from "../../UI/Card"; import FindList from "../../../entity/find/FindList"; import useGlobalHook from "../../../hooks/useGlobalHook"; import { getSession } from "../../../hooks/SessionStore"; const GlobalLeaderboardScreen = ({ navigation, route }) => { // Initialisations --------------------- const { eventId } = route.params; const { getFindsByEvent, getCachesByEvent, getPlayersByEvent } = useGlobalHook(); const session = getSession(); // State ------------------------------- const [isLoading, setIsLoading] = useState(true); const [rankings, setRankings] = useState([]); const [recentFinds, setRecentFinds] = useState([]); const [activeTab, setActiveTab] = useState("rankings"); // Handlers ---------------------------- const loadData = useCallback(async () => { setIsLoading(true); const [finds, caches, players] = await Promise.all([ getFindsByEvent(eventId), getCachesByEvent(eventId), getPlayersByEvent(eventId), ]); // Build cache points lookup const cacheMap = {}; (caches || []).forEach((c) => { cacheMap[c.CacheID] = c; }); // Augment finds with cache info for FindList const augmented = (finds || []).map((f) => ({ ...f, FindCache: f.FindCache || cacheMap[f.FindCacheID] || null, })); // Sort recent first const sorted = [...augmented].sort( (a, b) => new Date(b.FindDatetime) - new Date(a.FindDatetime), ); setRecentFinds(sorted.slice(0, 50)); // Aggregate points per player const pointsMap = {}; augmented.forEach((f) => { const pid = f.FindPlayerID; const pts = f.FindCache?.CachePoints ?? 0; if (!pointsMap[pid]) pointsMap[pid] = { playerId: pid, points: 0, finds: 0, name: null }; pointsMap[pid].points += pts; pointsMap[pid].finds += 1; }); // Attach usernames from players list (players || []).forEach((p) => { if (pointsMap[p.PlayerID]) { pointsMap[p.PlayerID].name = p.PlayerUser?.UserUsername || `Player #${p.PlayerUserID}`; } }); const ranked = Object.values(pointsMap).sort((a, b) => b.points - a.points); setRankings(ranked); setIsLoading(false); }, [eventId]); useEffect(() => { loadData(); }, [loadData]); // View -------------------------------- if (isLoading) { return ( ); } return ( setActiveTab("rankings")} /> setActiveTab("recentFinds")} /> {activeTab === "rankings" ? ( {rankings.length === 0 ? ( No finds recorded yet. ) : ( rankings.map((entry, index) => { const isCurrent = entry.playerId === session.currentGlobalPlayerId; return ( #{index + 1} {entry.name || `Player #${entry.playerId}`} {isCurrent ? " (you)" : ""} {entry.points} pts {entry.finds} finds ); }) )} ) : recentFinds.length === 0 ? ( No finds recorded yet. ) : ( )}