Compare commits
No commits in common. "88a4400307cc5d9cab004484c3feae145971593c" and "b5dbe91e8a72a7a23779e0ea04e14d9b495e8f53" have entirely different histories.
88a4400307
...
b5dbe91e8a
@ -1,85 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import styles from '../styles/Dashboard.module.css';
|
|
||||||
|
|
||||||
interface MetricsData {
|
|
||||||
totalPlayers: number;
|
|
||||||
totalRuns: number;
|
|
||||||
activePlayers24h: number;
|
|
||||||
totalBossesDefeated: number;
|
|
||||||
totalPrestigeLevelsGained: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SUBGRAPH_URL = "https://api.studio.thegraph.com/query/75782/slay-the-moloch-base-mainnet/version/latest";
|
|
||||||
|
|
||||||
const Dashboard = () => {
|
|
||||||
const [metrics, setMetrics] = useState<MetricsData>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchMetrics = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(SUBGRAPH_URL, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
query: `{
|
|
||||||
# Get global stats
|
|
||||||
globalStat(id: "1") {
|
|
||||||
totalPlayers
|
|
||||||
totalBossesDefeated
|
|
||||||
totalPrestigeLevels
|
|
||||||
totalRuns
|
|
||||||
}
|
|
||||||
# Get active players in last 24h
|
|
||||||
players(where: { lastRaidedAt_gt: "${Math.floor(Date.now() / 1000) - 86400}" }) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
setMetrics({
|
|
||||||
totalPlayers: parseInt(data.data.globalStat.totalPlayers),
|
|
||||||
totalRuns: parseInt(data.data.globalStat.totalRuns),
|
|
||||||
activePlayers24h: data.data.players.length,
|
|
||||||
totalBossesDefeated: parseInt(data.data.globalStat.totalBossesDefeated),
|
|
||||||
totalPrestigeLevels: parseInt(data.data.globalStat.totalPrestigeLevels)
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error fetching metrics:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchMetrics();
|
|
||||||
const interval = setInterval(fetchMetrics, 30000); // Refresh every 30 seconds
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.dashboard}>
|
|
||||||
<div className={styles.metric}>
|
|
||||||
<h3>Total Players</h3>
|
|
||||||
<p>{metrics?.totalPlayers || 0}</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.metric}>
|
|
||||||
<h3>Total Game Runs</h3>
|
|
||||||
<p>{metrics?.totalRuns || 0}</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.metric}>
|
|
||||||
<h3>Active Players (24h)</h3>
|
|
||||||
<p>{metrics?.activePlayers24h || 0}</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.metric}>
|
|
||||||
<h3>Total Bosses Defeated</h3>
|
|
||||||
<p>{metrics?.totalBossesDefeated || 0}</p>
|
|
||||||
</div>
|
|
||||||
<div className={styles.metric}>
|
|
||||||
<h3>Total Prestige Levels</h3>
|
|
||||||
<p>{metrics?.totalPrestigeLevels || 0}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Dashboard;
|
|
||||||
@ -8,7 +8,6 @@ import Leaderboard from "./Leaderboard";
|
|||||||
import { usePlayer } from "../providers/PlayerProvider";
|
import { usePlayer } from "../providers/PlayerProvider";
|
||||||
import Boss from "./Boss";
|
import Boss from "./Boss";
|
||||||
import BossInfo from "./BossInfo";
|
import BossInfo from "./BossInfo";
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
const bossToMountainsClass = {
|
const bossToMountainsClass = {
|
||||||
0: styles.mountains0,
|
0: styles.mountains0,
|
||||||
@ -54,7 +53,6 @@ const Scene = () => {
|
|||||||
>
|
>
|
||||||
🏆 <span className={styles.hideMobile}>Top players</span>
|
🏆 <span className={styles.hideMobile}>Top players</span>
|
||||||
</button>
|
</button>
|
||||||
<Link href="/metrics" className={styles.metricsButton}>📈 <span className={styles.hideMobile}>Game metrics</span></Link>
|
|
||||||
{isLeaderboardOpen && (
|
{isLeaderboardOpen && (
|
||||||
<div className={styles.leaderboardOverlay}>
|
<div className={styles.leaderboardOverlay}>
|
||||||
<div className={styles.leaderboardContent}>
|
<div className={styles.leaderboardContent}>
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
import Dashboard from '../components/Dashboard';
|
|
||||||
import styles from '../styles/Metrics.module.css';
|
|
||||||
import Link from 'next/link';
|
|
||||||
|
|
||||||
const MetricsPage = () => {
|
|
||||||
return (
|
|
||||||
<div className={styles.metricsPage}>
|
|
||||||
<Link href="/" className={styles.backLink}>← Back to game</Link>
|
|
||||||
<h1>Game Metrics</h1>
|
|
||||||
<Dashboard />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MetricsPage;
|
|
||||||
@ -402,8 +402,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.leaderboardButton,
|
.leaderboardButton {
|
||||||
.metricsButton {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
left: 80px;
|
left: 80px;
|
||||||
@ -426,12 +425,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.metricsButton {
|
|
||||||
left: auto;
|
|
||||||
top: auto;
|
|
||||||
right: 32px;
|
|
||||||
bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaderboardButton:hover {
|
.leaderboardButton:hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
.dashboard {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
padding: 2rem;
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric {
|
|
||||||
background: rgba(0, 0, 0, 0.8);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 1.5rem;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric h3 {
|
|
||||||
color: #888;
|
|
||||||
margin: 0 0 1rem 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metric p {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 2rem;
|
|
||||||
margin: 0;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
.metricsPage {
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 2rem;
|
|
||||||
background: #1a1a1a;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metricsPage h1 {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backLink {
|
|
||||||
display: inline-block;
|
|
||||||
color: #888;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backLink:hover {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user