From 3332eaf81eafb404c128604182cae7269b4f8914 Mon Sep 17 00:00:00 2001 From: syahirAmali Date: Fri, 1 Nov 2024 23:08:54 +0800 Subject: [PATCH] Leaderboard update --- app/src/components/Leaderboard.tsx | 271 ++++++++++++++++++++--------- app/src/types/leaderboard.ts | 54 +++--- 2 files changed, 217 insertions(+), 108 deletions(-) diff --git a/app/src/components/Leaderboard.tsx b/app/src/components/Leaderboard.tsx index 47f7287..f26b0fd 100644 --- a/app/src/components/Leaderboard.tsx +++ b/app/src/components/Leaderboard.tsx @@ -1,24 +1,33 @@ -import { useEffect, useState } from 'react' -import styles from '../styles/Leaderboard.module.css' -import { TopEarnersResponse, TopRaidersResponse } from '../types/leaderboard' -import { formatUnits } from 'viem' +import { useEffect, useState } from "react"; +import styles from "../styles/Leaderboard.module.css"; +import { + TopEarnersResponse, + TopRaidersResponse, + PlayerResponse, +} from "../types/leaderboard"; +import { formatUnits } from "viem"; -const SUBGRAPH_URL = 'https://api.studio.thegraph.com/query/75782/slay-the-moloch-base-sepolia/version/latest' +const SUBGRAPH_URL = + "https://api.studio.thegraph.com/query/75782/slay-the-moloch-base-mainnet/version/latest"; const Leaderboard = () => { - const [topEarners, setTopEarners] = useState() - const [topRaiders, setTopRaiders] = useState() - const [activeTab, setActiveTab] = useState<'earners' | 'raiders'>('earners') + const [topEarners, setTopEarners] = useState(); + const [topRaiders, setTopRaiders] = useState(); + const [activeTab, setActiveTab] = useState< + "earners" | "raiders" | "bosses" | "prestige" + >("earners"); + const [bossesDefeated, setBossesDefeated] = useState(); + const [playerPrestige, setPlayerPrestige] = useState(); - useEffect(() => { - const fetchLeaderboards = async () => { - try { - // Fetch top earners - const earnersResponse = await fetch(SUBGRAPH_URL, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - query: `{ + useEffect(() => { + const fetchLeaderboards = async () => { + try { + // Fetch top earners + const earnersResponse = await fetch(SUBGRAPH_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + query: `{ armies(first: 10, orderBy: profitPerSecond, orderDirection: desc) { player { id @@ -32,83 +41,177 @@ const Leaderboard = () => { anointedLevel championLevel } - }` - }) - }) - const earnersData = await earnersResponse.json() - setTopEarners({ armies: earnersData.data.armies }) + }`, + }), + }); + const earnersData = await earnersResponse.json(); + setTopEarners({ armies: earnersData.data.armies }); - // Fetch top raiders - const raidersResponse = await fetch(SUBGRAPH_URL, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - query: `{ + // Fetch top raiders + const raidersResponse = await fetch(SUBGRAPH_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + query: `{ players(first: 10, orderBy: numberOfRaids, orderDirection: desc) { id numberOfRaids totalMinted currentBalance } - }` - }) - }) - const raidersData = await raidersResponse.json() - setTopRaiders({ players: raidersData.data.players }) - } catch (error) { - console.error('Error fetching leaderboard:', error) - } - } + }`, + }), + }); + const raidersData = await raidersResponse.json(); + setTopRaiders({ players: raidersData.data.players }); - fetchLeaderboards() - const interval = setInterval(fetchLeaderboards, 30000) // Refresh every 30 seconds - return () => clearInterval(interval) - }, []) + // Fetch bosses defeated + const bossesDefeatedResponse = await fetch(SUBGRAPH_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + query: `{ + players(first: 10, orderBy: bossesDefeated, orderDirection: desc) { + id + bossesDefeated + } + }`, + }), + }); + const bossesDefeatedData = await bossesDefeatedResponse.json(); + setBossesDefeated({ players: bossesDefeatedData.data.players }); - return ( -
-

Leaderboard

- -
- - -
+ // Fetch player prestige + const playerPrestigeResponse = await fetch(SUBGRAPH_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + query: `{ + players(first: 10, orderBy: prestigeLevel, orderDirection: desc) { + id + prestigeLevel + } + }`, + }), + }); + const playerPrestigeData = await playerPrestigeResponse.json(); + setPlayerPrestige({ players: playerPrestigeData.data.players }); + } catch (error) { + console.error("Error fetching leaderboard:", error); + } + }; - {activeTab === 'earners' && ( -
- {topEarners?.armies.map((army, index) => ( -
- #{index + 1} - {army.player.id.slice(0, 6)}...{army.player.id.slice(-4)} - {formatUnits(BigInt(army.profitPerSecond), 4)} GELD/s + fetchLeaderboards(); + const interval = setInterval(fetchLeaderboards, 30000); // Refresh every 30 seconds + return () => clearInterval(interval); + }, []); + + return ( +
+

Leaderboard

+ +
+ + + +
- ))} -
- )} - {activeTab === 'raiders' && ( -
- {topRaiders?.players.map((player, index) => ( -
- #{index + 1} - {player.id.slice(0, 6)}...{player.id.slice(-4)} - {player.numberOfRaids} raids -
- ))} -
- )} -
- ) -} + {activeTab === "earners" && ( +
+ {topEarners?.armies.map((army, index) => ( +
+ #{index + 1} + + {army.player.id.slice(0, 6)}... + {army.player.id.slice(-4)} + + + {formatUnits(BigInt(army.profitPerSecond), 4)}{" "} + GELD/s + +
+ ))} +
+ )} -export default Leaderboard \ No newline at end of file + {activeTab === "raiders" && ( +
+ {topRaiders?.players.map((player, index) => ( +
+ #{index + 1} + + {player.id.slice(0, 6)}...{player.id.slice(-4)} + + + {player.numberOfRaids} raids + +
+ ))} +
+ )} + + {activeTab === "bosses" && ( +
+ {bossesDefeated?.players.map((player, index) => ( +
+ #{index + 1} + + {player.id.slice(0, 6)}...{player.id.slice(-4)} + + + {player.bossesDefeated} Bosses Slain + +
+ ))} +
+ )} + + {activeTab === "prestige" && ( +
+ {playerPrestige?.players.map((player, index) => ( +
+ #{index + 1} + + {player.id.slice(0, 6)}...{player.id.slice(-4)} + + + {player.prestigeLevel} Prestige Level + +
+ ))} +
+ )} +
+ ); +}; + +export default Leaderboard; diff --git a/app/src/types/leaderboard.ts b/app/src/types/leaderboard.ts index ef2507d..6030eae 100644 --- a/app/src/types/leaderboard.ts +++ b/app/src/types/leaderboard.ts @@ -1,25 +1,31 @@ export interface Player { - id: string - totalMinted: string - currentBalance: string - numberOfRaids: string - army?: Army - } - - export interface Army { - player: Player - profitPerSecond: string - projectedDailyEarnings: string - molochDenierLevel: string - apprenticeLevel: string - anointedLevel: string - championLevel: string - } - - export interface TopEarnersResponse { - armies: Army[] - } - - export interface TopRaidersResponse { - players: Player[] - } \ No newline at end of file + id: string; + totalMinted: string; + currentBalance: string; + numberOfRaids: string; + army?: Army; + bossesDefeated?: string; + prestigeLevel: string; +} + +export interface Army { + player: Player; + profitPerSecond: string; + projectedDailyEarnings: string; + molochDenierLevel: string; + apprenticeLevel: string; + anointedLevel: string; + championLevel: string; +} + +export interface TopEarnersResponse { + armies: Army[]; +} + +export interface TopRaidersResponse { + players: Player[]; +} + +export interface PlayerResponse { + players: Player[]; +} -- 2.39.2