diff --git a/src/components/GameView/GameView.tsx b/src/components/GameView/GameView.tsx index dcfbc1e8..3733d17c 100644 --- a/src/components/GameView/GameView.tsx +++ b/src/components/GameView/GameView.tsx @@ -4,6 +4,7 @@ import GlobalTPS from "../GlobalTPS"; import Layout from "../Layout"; import MusicPlayer from "../MusicPlayer"; import RestartButton from "../RestartButton"; +import SessionStats from "../SessionStats"; import TopLinks from "../TopLinks"; const GameView = () => { @@ -13,7 +14,10 @@ const GameView = () => {
- +
+ + +
diff --git a/src/components/SessionStats/SessionStats.tsx b/src/components/SessionStats/SessionStats.tsx new file mode 100644 index 00000000..fb76118d --- /dev/null +++ b/src/components/SessionStats/SessionStats.tsx @@ -0,0 +1,76 @@ +import { FC } from "react"; +import StatsCard from "../StatsCard"; +import { StatsCardProps } from "../StatsCard/StatsCard"; +import { useAppContext } from "../../context/useAppContext"; +import { formatNumber } from "../../utils/numbers"; +import { useQuery } from "@tanstack/react-query"; +import { fetchSessionStats } from "../../utils/requests"; +import { SessionStatsInterface } from "../../types"; +import { FaStar } from "react-icons/fa6"; +import cx from "classnames"; + +const SessionStats: FC> = ({ + size, + titleAlign, +}) => { + const { keys, accountData } = useAppContext(); + const { publicKeyHashHex = "" } = keys || {}; + + const { data } = useQuery({ + queryKey: ["sessionStats", publicKeyHashHex], + queryFn: () => fetchSessionStats(publicKeyHashHex), + enabled: !!publicKeyHashHex && !!accountData, + refetchInterval: 6000, // 6 seconds + }); + + const { death = 0, game_started = 0, kill = 0 } = data || {}; + + const stats = [ + { + label: "Games Played:", + value: game_started, + showStar: game_started > 0, + starColor: game_started >= 4 ? "text-yellow-400" : "text-white", + }, + { + label: "Kills:", + value: kill, + showStar: kill >= 25, + starColor: kill >= 50 ? "text-yellow-400" : "text-white", + }, + { + label: "Deaths:", + value: death, + showStar: false, + starColor: null, + }, + ]; + + const formattedStats = stats.map(({ label, value, showStar, starColor }) => { + const formattedValue = formatNumber(value); + return { + label, + value: showStar ? ( +
+
{formattedValue}
+ +
+ ) : ( + formattedValue + ), + }; + }); + + if (!accountData) return null; + + return ( + + ); +}; + +export default SessionStats; diff --git a/src/components/SessionStats/index.ts b/src/components/SessionStats/index.ts new file mode 100644 index 00000000..99732581 --- /dev/null +++ b/src/components/SessionStats/index.ts @@ -0,0 +1 @@ +export { default } from "./SessionStats"; diff --git a/src/components/StatsCard/StatsCard.tsx b/src/components/StatsCard/StatsCard.tsx index 6a310cdf..97329ae8 100644 --- a/src/components/StatsCard/StatsCard.tsx +++ b/src/components/StatsCard/StatsCard.tsx @@ -1,9 +1,9 @@ -import { FC } from "react"; +import { FC, ReactNode } from "react"; import Card from "../Card"; import cx from "classnames"; export interface StatsCardProps { - data: { label: string; value: string | number }[]; + data: { label: string; value: ReactNode }[]; size?: "sm" | "md" | "lg"; title?: string; titleAlign?: "left" | "center" | "right"; @@ -48,8 +48,8 @@ const StatsCard: FC = ({ {data.map((item) => ( - {item.label} - {item.value} + {item.label} + {item.value} ))} diff --git a/src/types.ts b/src/types.ts index d667c64f..fa78ef31 100644 --- a/src/types.ts +++ b/src/types.ts @@ -116,3 +116,13 @@ export interface Region { name: string; value: string; } + +export interface SessionStatsInterface { + death: number; + game_finished: number; + game_started: number; + kill: number; + new_game: number; + player_joined: number; + suicide: number; +} diff --git a/src/utils/requests.ts b/src/utils/requests.ts index b0c68e63..186ab924 100644 --- a/src/utils/requests.ts +++ b/src/utils/requests.ts @@ -1,5 +1,5 @@ import { API_BASE_URL, API_KEY } from "../constants"; -import { AuthResponse, GameStatistics } from "../types"; +import { AuthResponse, GameStatistics, SessionStatsInterface } from "../types"; export const fetchAuthProviders = async (): Promise => { const response = await fetch(`${API_BASE_URL}/auth/providers`); @@ -55,3 +55,15 @@ export const authRefresh = async ({ } return response.json(); }; + +export const fetchSessionStats = async ( + sessionReference: string, +): Promise => { + const response = await fetch( + `${API_BASE_URL}/stats/session/${API_KEY}/${sessionReference}`, + ); + if (!response.ok) { + throw new Error("Failed to fetch session stats"); + } + return response.json(); +};