Skip to content

Commit

Permalink
Merge pull request #104 from game-node-app/dev
Browse files Browse the repository at this point in the history
Profile stats screen
  • Loading branch information
Lamarcke authored Jul 21, 2024
2 parents 387f3ec + 7082416 commit d557d5e
Show file tree
Hide file tree
Showing 24 changed files with 678 additions and 45 deletions.
6 changes: 4 additions & 2 deletions src/components/achievement/AchievementItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ const AchievementItem = ({ targetUserId, achievement }: Props) => {
</Text>
</Stack>
<Stack ml={"auto"} gap={0} justify={"center"} align={"center"}>
<Title fz={"1.5rem"} className={"break-keep"}>
<Title fz={"1.5rem"} className={"break-keep text-center"}>
{achievement.expGainAmount} XP
</Title>
<Text fz={"0.5rem"}>{obtainedText}</Text>
<Text fz={"0.5rem"} className={"text-center"}>
{obtainedText}
</Text>
</Stack>
</Group>
</Paper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ export function useFeaturedObtainedAchievement(
queryKey,
queryFn: async () => {
if (!userId) {
return undefined;
return null;
}

const featuredAchivement =
await AchievementsService.achievementsControllerGetFeaturedAchievementForUserId(
userId,
);

if (!featuredAchivement) {
return null;
}

return featuredAchivement;
},
enabled: !!userId,
Expand Down
4 changes: 2 additions & 2 deletions src/components/game/figure/GameGridFigure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import GameFigureImage, {
IGameFigureProps,
} from "@/components/game/figure/GameFigureImage";
import { Badge } from "@mantine/core";
import { getGameCategoryText } from "@/components/game/util/getGameCategoryText";
import { getGameCategoryName } from "@/components/game/util/getGameCategoryName";
import { TGameOrSearchGame } from "@/components/game/util/types";

interface IGameGridFigureProps {
Expand All @@ -13,7 +13,7 @@ interface IGameGridFigureProps {

const GameGridFigure = ({ game, figureProps }: IGameGridFigureProps) => {
const categoryText = useMemo(
() => getGameCategoryText(game?.category),
() => getGameCategoryName(game?.category),
[game],
);
return (
Expand Down
4 changes: 2 additions & 2 deletions src/components/game/figure/GameListFigure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { getLocalizedFirstReleaseDate } from "@/components/game/util/getLocalize
import { TGameOrSearchGame } from "@/components/game/util/types";
import { getGameGenres } from "@/components/game/util/getGameGenres";
import { getGamePlatformInfo } from "@/components/game/util/getGamePlatformInfo";
import { getGameCategoryText } from "@/components/game/util/getGameCategoryText";
import { getGameCategoryName } from "@/components/game/util/getGameCategoryName";
import GameInfoPlatforms from "@/components/game/info/GameInfoPlatforms";

interface IGameListFigureProps {
Expand All @@ -40,7 +40,7 @@ const GameListFigure = ({ game, figureProps }: IGameListFigureProps) => {
const genres = getGameGenres(game);
const genreNames = genres?.join(", ");
const categoryText = useMemo(
() => getGameCategoryText(game?.category),
() => getGameCategoryName(game?.category),
[game.category],
);

Expand Down
26 changes: 26 additions & 0 deletions src/components/game/util/getGameCategoryName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Game } from "@/wrapper/server";

/**
* Based on a game's category id, retrieves its readable name.
* @param category
*/
export function getGameCategoryName(category?: number) {
const CATEGORY_TO_TEXT = {
[Game.category._1.valueOf()]: "DLC",
[Game.category._2.valueOf()]: "DLC",
[Game.category._3.valueOf()]: "Bundle",
[Game.category._4.valueOf()]: "Expansion",
[Game.category._5.valueOf()]: "Mod",
[Game.category._6.valueOf()]: "Episode",
[Game.category._7.valueOf()]: "Season",
[Game.category._8.valueOf()]: "Remake",
[Game.category._9.valueOf()]: "Remaster",
[Game.category._10.valueOf()]: "Expanded Game",
[Game.category._11.valueOf()]: "Port",
[Game.category._12.valueOf()]: "Fork",
[Game.category._13.valueOf()]: "Pack",
[Game.category._14.valueOf()]: "Update",
};
if (!category) return undefined;
return CATEGORY_TO_TEXT[category];
}
14 changes: 0 additions & 14 deletions src/components/game/util/getGameCategoryText.ts

This file was deleted.

29 changes: 29 additions & 0 deletions src/components/general/RoundedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, {
ExoticComponent,
PropsWithChildren,
PropsWithoutRef,
} from "react";
import { IconBrandXbox, IconProps } from "@tabler/icons-react";
import { Box, BoxProps, ThemeIcon, ThemeIconProps } from "@mantine/core";

interface RoundedIconProps {
icon: ExoticComponent<PropsWithoutRef<IconProps>>;
iconProps?: PropsWithoutRef<IconProps>;
wrapperProps?: PropsWithoutRef<ThemeIconProps>;
}

const RoundedIcon = (props: RoundedIconProps) => {
return (
<ThemeIcon
radius={"50%"}
variant={"outline"}
p={12}
className={"w-fit h-fit min-w-fit bg-[#161616] border-[#161616]"}
{...props.wrapperProps}
>
<props.icon size={"3rem"} {...props.iconProps} />
</ThemeIcon>
);
};

export default RoundedIcon;
4 changes: 2 additions & 2 deletions src/components/general/shell/GlobalAppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ const GlobalAppShell = ({ children }: { children: React.ReactNode }) => {
<GlobalShellNavbar onClose={modalUtils.close} />
</AppShell.Navbar>
{/**
Remove 'ps=0' to make the sidebar push the main content to its right when opened
Remove '!ps-2.5' to make the sidebar push the main content to its right when opened
*/}
<AppShell.Main
pos={"relative"}
className={"!ps-0 xl:flex xl:justify-center"}
className={"!ps-2.5 xl:flex xl:justify-center"}
>
<Box className={"w-full xl:max-w-screen-xl"}>{children}</Box>
</AppShell.Main>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from "react";
import { useAchievements } from "@/components/achievement/hooks/useAchievements";
import { Center, Modal, Select, Stack, Text } from "@mantine/core";
import { Center, Group, Modal, Select, Stack, Text } from "@mantine/core";
import { useFeaturedObtainedAchievement } from "@/components/achievement/hooks/useFeaturedObtainedAchievement";
import useUserId from "@/components/auth/hooks/useUserId";
import AchievementItem from "@/components/achievement/AchievementItem";
Expand Down Expand Up @@ -74,7 +74,11 @@ const ProfileEditFeaturedAchievement = () => {
achievements.data == undefined ||
allObtainedAchievements.data == undefined
) {
return null;
return (
<Group>
<Text>No obtained achievement found.</Text>
</Group>
);
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useQuery } from "@tanstack/react-query";
import { ProfileMetricsService } from "@/wrapper/server";

export type ProfileMetricsDistributionTypeBy =
| "genre"
| "category"
| "mode"
| "platform";

export function useProfileMetricsDistributionByType(
userId: string,
by: ProfileMetricsDistributionTypeBy,
) {
return useQuery({
queryKey: ["profile", "metrics", "distribution", "type", userId, by],
queryFn: async () => {
return ProfileMetricsService.profileMetricsControllerGetTypeDistribution(
userId,
by,
);
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useQuery } from "@tanstack/react-query";
import { ProfileMetricsService } from "@/wrapper/server";

export type ProfileMetricsDistributionYearBy = "release_year" | "finish_year";

export function useProfileMetricsDistributionByYear(
userId: string | undefined,
by: ProfileMetricsDistributionYearBy,
) {
return useQuery({
queryKey: ["profile", "metrics", "distribution", userId, by],
queryFn: async () => {
if (!userId) return null;
return ProfileMetricsService.profileMetricsControllerGetYearDistribution(
userId,
by,
);
},
enabled: !!userId,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { DetailsBox } from "@/components/general/DetailsBox";
import { BarChart } from "@mantine/charts";
import { ProfileMetricsOverviewDto } from "@/wrapper/server";
import TextLink from "@/components/general/TextLink";

interface Props {
userId: string;
Expand All @@ -31,7 +32,7 @@ const buildBarChartData = (data: ProfileMetricsOverviewDto) => {
];
};

const ProfileStatsOverview = ({ userId }: Props) => {
const ProfileStatsSimpleOverview = ({ userId }: Props) => {
const metricsOverviewQuery = useProfileMetricsOverview(userId);

const playtimeValue =
Expand All @@ -40,18 +41,20 @@ const ProfileStatsOverview = ({ userId }: Props) => {

return (
<Group className={"w-full"}>
<Group className={"w-full justify-between"}>
<Group className={"w-full justify-between flex-nowrap"}>
<Stack className={"gap-1"}>
<Text className={"text-md text-center"}>
{metricsOverviewQuery.data?.totalGames}
</Text>
<Text className={"text-sm text-dimmed"}>Total games</Text>
<Text className={"text-sm text-dimmed text-center"}>
Total games
</Text>
</Stack>
<Stack className={"gap-1"}>
<Text className={"text-sm text-center"}>
{metricsOverviewQuery.data?.totalFinishedGames}
</Text>
<Text className={"text-sm text-dimmed"}>
<Text className={"text-sm text-dimmed text-center"}>
Finished games
</Text>
</Stack>
Expand All @@ -66,8 +69,8 @@ const ProfileStatsOverview = ({ userId }: Props) => {
shadow="md"
>
<Popover.Target>
<Text className={"text-sm text-dimmed"}>
Estimated playtime*
<Text className={"text-sm text-dimmed text-center"}>
Estimated playtime (in hours)*
</Text>
</Popover.Target>
<Popover.Dropdown>
Expand Down Expand Up @@ -119,8 +122,11 @@ const ProfileStatsOverview = ({ userId }: Props) => {
/>
</Group>
)}
<TextLink href={`/profile/${userId}/stats`} className={"mt-3"}>
Show more
</TextLink>
</Group>
);
};

export default ProfileStatsOverview;
export default ProfileStatsSimpleOverview;
5 changes: 5 additions & 0 deletions src/components/profile/view/ProfileViewNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const ProfileViewNavbar = ({ userId, ...groupProps }: Props) => {
targetUserId={userId}
criteria={criteria.FOLLOWING}
/>
<ProfileViewNavbarLink
title={"Stats"}
showItemCount={false}
href={`/profile/${userId}/stats`}
/>
</SimpleGrid>
);
};
Expand Down
10 changes: 8 additions & 2 deletions src/components/profile/view/ProfileViewNavbarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import Link from "next/link";
interface Props extends ComponentPropsWithoutRef<typeof Link> {
title: string;
itemCount?: number;
showItemCount?: boolean;
}

const ProfileViewNavbarLink = ({
title,
itemCount = 0,
showItemCount = true,
...linkProps
}: Props) => {
return (
Expand All @@ -18,8 +20,12 @@ const ProfileViewNavbarLink = ({
{...linkProps}
>
<Text className={"text-lg lg:text-xl text-center"}>{title}</Text>
<Divider className={"w-full"} />
<Text className={"text-sm text-dimmed"}>{itemCount}</Text>
{showItemCount && (
<>
<Divider className={"w-full"} />
<Text className={"text-sm text-dimmed"}>{itemCount}</Text>
</>
)}
</Link>
);
};
Expand Down
35 changes: 35 additions & 0 deletions src/components/profile/view/stats/ProfileStatsDataIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { ExoticComponent, PropsWithoutRef } from "react";
import { IconDeviceGamepad2, IconProps } from "@tabler/icons-react";
import { Group, Stack, Text, Title } from "@mantine/core";
import RoundedIcon from "@/components/general/RoundedIcon";

interface ProfileStatsDataIconProps {
description: string;
count?: number;
icon: ExoticComponent<PropsWithoutRef<IconProps>>;
}

const ProfileStatsDataIcon = ({
description,
count = 0,
icon,
}: ProfileStatsDataIconProps) => {
return (
<Group className={"gap-2 flex-nowrap"}>
<RoundedIcon
icon={icon}
iconProps={{
size: "3rem",
}}
/>
<Stack className={"gap-0.5"}>
<Title size={"h2"} className={"text-brand-4"}>
{count}
</Title>
<Text className={"text-md"}>{description}</Text>
</Stack>
</Group>
);
};

export default ProfileStatsDataIcon;
Loading

0 comments on commit d557d5e

Please sign in to comment.