revert to client sided data fetching

This commit is contained in:
Lee
2023-10-24 11:18:51 +01:00
parent fe0be93d3e
commit e77e07423a
15 changed files with 700 additions and 573 deletions

@ -1,124 +0,0 @@
import Card from "@/components/Card";
import Container from "@/components/Container";
import Error from "@/components/Error";
import PlayerInfo from "@/components/player/PlayerInfo";
import Scores from "@/components/player/Scores";
import { ssrSettings } from "@/ssrSettings";
import { SortTypes } from "@/types/SortTypes";
import { formatNumber } from "@/utils/number";
import { ScoreSaberAPI } from "@/utils/scoresaber/api";
import { normalizedRegionName } from "@/utils/utils";
import { Metadata } from "next";
type PlayerPageProps = {
params: { id: string; leaderboard: string; sort: string; page: string };
};
const DEFAULT_SORT_TYPE = SortTypes.top;
// Get data from API (server-sided)
async function getData(playerId: string, sort?: string, page?: number) {
const playerData = await ScoreSaberAPI.fetchPlayerData(playerId);
if (!playerData) {
return undefined;
}
const scores = [];
let totalPages = -1;
if (sort && page) {
const scoresData = await ScoreSaberAPI.fetchScores(
playerId,
page,
sort,
10,
);
if (scoresData) {
scores.push(...scoresData.scores);
totalPages = scoresData.pageInfo.totalPages;
}
}
return { player: playerData, scores: scores, totalPages: totalPages };
}
export async function generateMetadata({
params: { id, leaderboard, sort, page },
}: PlayerPageProps): Promise<Metadata> {
const data = await getData(id, sort, Number(page));
if (!data) {
return {
title: "Player not found",
};
}
const player = data.player;
const description = `
View ${player.name}'s scores, top plays, and more.
Rank: #${formatNumber(player.rank)} (#${formatNumber(
player.countryRank,
)} - ${normalizedRegionName(player.country)})
PP: ${formatNumber(player.pp)}
Play Count: ${formatNumber(player.scoreStats.totalPlayCount)}`;
return {
title: `${player.name}`,
description: `View ${player.name}'s scores, top plays, and more.`,
openGraph: {
siteName: ssrSettings.siteName,
title: `${player.name}`,
description: description,
images: [
{
url: player.profilePicture,
},
],
},
twitter: {
card: "summary",
},
};
}
export default async function Player({
params: { id, leaderboard, sort, page },
}: PlayerPageProps) {
const playerData = await getData(id, sort, Number(page));
const currentPage = Number(page);
const sortType = SortTypes[sort] || DEFAULT_SORT_TYPE;
if (!playerData) {
return (
<main>
<Container>
<Card className="mt-2">
<Error errorMessage="Failed to load player. Is the ID valid?" />
</Card>
</Container>
</main>
);
}
const player = playerData.player;
const scores = playerData.scores;
return (
<main>
<Container>
<Card className="mt-2">
<PlayerInfo playerData={player} />
</Card>
<Card className="mt-2">
<Scores
playerData={player}
page={currentPage}
sortType={sortType}
scores={scores}
totalPages={playerData.totalPages}
/>
</Card>
</Container>
</main>
);
}

@ -0,0 +1,52 @@
import PlayerPage from "@/components/player/PlayerPage";
import { ssrSettings } from "@/ssrSettings";
import { formatNumber } from "@/utils/number";
import { ScoreSaberAPI } from "@/utils/scoresaber/api";
import { normalizedRegionName } from "@/utils/utils";
import { Metadata } from "next";
type Props = {
params: { id: string };
};
export async function generateMetadata({
params: { id },
}: Props): Promise<Metadata> {
const player = await ScoreSaberAPI.fetchPlayerData(id);
if (!player) {
return {
title: "Player not found",
};
}
const description = `
View ${player.name}'s scores, top plays, and more.
Rank: #${formatNumber(player.rank)} (#${formatNumber(
player.countryRank,
)} - ${normalizedRegionName(player.country)})
PP: ${formatNumber(player.pp)}
Play Count: ${formatNumber(player.scoreStats.totalPlayCount)}`;
return {
title: `${player.name}`,
description: `View ${player.name}'s scores, top plays, and more.`,
openGraph: {
siteName: ssrSettings.siteName,
title: `${player.name}`,
description: description,
images: [
{
url: player.profilePicture,
},
],
},
twitter: {
card: "summary",
},
};
}
export default function Player({ params: { id } }: Props) {
return <PlayerPage id={id} />;
}

@ -1,44 +0,0 @@
import Card from "@/components/Card";
import Container from "@/components/Container";
import Error from "@/components/Error";
import GlobalRanking from "@/components/player/GlobalRanking";
import { ScoreSaberAPI } from "@/utils/scoresaber/api";
type RankingGlobalProps = {
params: { page: string; country: string };
};
// Get data from API (server-sided)
async function getData(page: number, country: string) {
const pageData = await ScoreSaberAPI.fetchTopPlayers(page, country);
if (!pageData) {
return undefined;
}
return pageData;
}
export default async function RankingGlobal({
params: { page, country },
}: RankingGlobalProps) {
const pageData = await getData(Number(page), country);
return (
<main>
<Container>
<Card className="mt-2">
{pageData == undefined && (
<Error errorMessage="Failed to load players. Is the page valid?" />
)}
{pageData && (
<GlobalRanking
page={Number(page)}
players={pageData.players}
totalPages={pageData.pageInfo.totalPages}
country={country}
/>
)}
</Card>
</Container>
</main>
);
}

@ -0,0 +1,14 @@
import GlobalRanking from "@/components/player/GlobalRanking";
import { getPageFromSearchQuery } from "@/utils/utils";
import { headers } from "next/headers";
type RankingCountryProps = {
params: { country: string };
};
export default function RankingCountry({ params }: RankingCountryProps) {
const page = getPageFromSearchQuery(headers());
const country = params.country;
return <GlobalRanking page={page} country={country} />;
}

@ -1,43 +0,0 @@
import Card from "@/components/Card";
import Container from "@/components/Container";
import Error from "@/components/Error";
import GlobalRanking from "@/components/player/GlobalRanking";
import { ScoreSaberAPI } from "@/utils/scoresaber/api";
type RankingGlobalProps = {
params: { page: string };
};
// Get data from API (server-sided)
async function getData(page: number) {
const pageData = await ScoreSaberAPI.fetchTopPlayers(page);
if (!pageData || pageData.players.length == 0) {
return undefined;
}
return pageData;
}
export default async function RankingGlobal({
params: { page },
}: RankingGlobalProps) {
const pageData = await getData(Number(page));
return (
<main>
<Container>
<Card className="mt-2">
{pageData == undefined && (
<Error errorMessage="Failed to load players. Is the page valid?" />
)}
{pageData && (
<GlobalRanking
page={Number(page)}
players={pageData.players}
totalPages={pageData.pageInfo.totalPages}
/>
)}
</Card>
</Container>
</main>
);
}

@ -0,0 +1,9 @@
import GlobalRanking from "@/components/player/GlobalRanking";
import { getPageFromSearchQuery } from "@/utils/utils";
import { headers } from "next/headers";
export default function RankingGlobal() {
const page = getPageFromSearchQuery(headers());
return <GlobalRanking page={page} />;
}