feat: create stats box

This commit is contained in:
Zamitto 2024-12-20 10:14:21 -03:00
parent 076f33605a
commit be89e0d60b
5 changed files with 83 additions and 4 deletions

View File

@ -359,7 +359,10 @@
"your_friend_code": "Your friend code:",
"upload_banner": "Upload banner",
"uploading_banner": "Uploading banner…",
"background_image_updated": "Background image updated"
"background_image_updated": "Background image updated",
"stats": "Stats",
"achievements": "Achievements",
"games": "Games"
},
"achievement": {
"achievement_unlocked": "Achievement unlocked",

View File

@ -357,7 +357,10 @@
"your_friend_code": "Seu código de amigo:",
"upload_banner": "Carregar banner",
"uploading_banner": "Carregando banner…",
"background_image_updated": "Imagem de fundo salva"
"background_image_updated": "Imagem de fundo salva",
"stats": "Estatísticas",
"achievements": "Conquistas",
"games": "Jogos"
},
"achievement": {
"achievement_unlocked": "Conquista desbloqueada",

View File

@ -21,6 +21,7 @@ import {
formatDownloadProgress,
} from "@renderer/helpers";
import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
import { UserStatsBox } from "./user-stats-box";
export function ProfileContent() {
const { userProfile, isMe, userStats } = useContext(userProfileContext);
@ -248,6 +249,7 @@ export function ProfileContent() {
{shouldShowRightContent && (
<div className={styles.rightContent}>
<UserStatsBox />
<RecentGamesBox />
<FriendsBox />

View File

@ -0,0 +1,65 @@
import * as styles from "./profile-content.css";
import { useCallback, useContext } from "react";
import { userProfileContext } from "@renderer/context";
import { useTranslation } from "react-i18next";
import { useFormat } from "@renderer/hooks";
import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
export function UserStatsBox() {
const { userStats } = useContext(userProfileContext);
const { t } = useTranslation("user_profile");
const { numberFormatter } = useFormat();
const formatPlayTime = useCallback(
(playTimeInSeconds: number) => {
const seconds = playTimeInSeconds;
const minutes = seconds / 60;
if (minutes < MAX_MINUTES_TO_SHOW_IN_PLAYTIME) {
return t("amount_minutes", {
amount: minutes.toFixed(0),
});
}
const hours = minutes / 60;
return t("amount_hours", { amount: numberFormatter.format(hours) });
},
[numberFormatter, t]
);
if (!userStats) return null;
return (
<div>
<div className={styles.sectionHeader}>
<h2>{t("stats")}</h2>
</div>
<div className={styles.box}>
<ul className={styles.list}>
{userStats.achievementsPointsEarnedSum && (
<li>
<p className={styles.listItemTitle}>{t("achievements")}</p>
<p>
Total points: {userStats.achievementsPointsEarnedSum.value} -
Top {userStats.achievementsPointsEarnedSum.topPercentile}%{" "}
</p>
<p>Unlocked: {userStats.unlockedAchievementSum}</p>
</li>
)}
<li>
<p className={styles.listItemTitle}>{t("games")}</p>
<p>
Total playtime:{" "}
{formatPlayTime(userStats.totalPlayTimeInSeconds.value)} - Top{" "}
{userStats.totalPlayTimeInSeconds.topPercentile}%
</p>
</li>
</ul>
</div>
</div>
);
}

View File

@ -320,11 +320,17 @@ export interface TrendingGame {
logo: string | null;
}
export interface UserStatsPercentile {
value: number;
topPercentile: number;
}
export interface UserStats {
libraryCount: number;
friendsCount: number;
achievementsPointsEarnedSum?: number;
totalPlaytimeInSeconds: number;
totalPlayTimeInSeconds: UserStatsPercentile;
achievementsPointsEarnedSum?: UserStatsPercentile;
unlockedAchievementSum?: number;
}
export interface UnlockedAchievement {