make ranking pages mobile friendly
All checks were successful
deploy / deploy (push) Successful in 1m1s

This commit is contained in:
Lee 2023-10-22 06:53:53 +01:00
parent 36d71d3b3a
commit f5ac6859b8
3 changed files with 116 additions and 28 deletions

@ -6,9 +6,11 @@ import Error from "@/components/Error";
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
import PlayerRanking from "@/components/player/PlayerRanking"; import PlayerRanking from "@/components/player/PlayerRanking";
import PlayerRankingMobile from "@/components/player/PlayerRankingMobile";
import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { fetchTopPlayers } from "@/utils/scoresaber/api"; import { fetchTopPlayers } from "@/utils/scoresaber/api";
import { normalizedRegionName } from "@/utils/utils"; import { normalizedRegionName } from "@/utils/utils";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import ReactCountryFlag from "react-country-flag"; import ReactCountryFlag from "react-country-flag";
@ -127,7 +129,7 @@ export default function RankingCountry({ params }: RankingCountryProps) {
</p> </p>
</div> </div>
<table className="w-full table-auto border-spacing-2 border-none text-left"> <table className="hidden w-full table-auto border-spacing-2 border-none text-left md:table">
<thead> <thead>
<tr> <tr>
<th className="px-4 py-2">Rank</th> <th className="px-4 py-2">Rank</th>
@ -146,21 +148,34 @@ export default function RankingCountry({ params }: RankingCountryProps) {
))} ))}
</tbody> </tbody>
</table> </table>
<div className="flex flex-col gap-2 md:hidden">
{players.map((player) => (
<div
key={player.rank}
className="flex flex-col gap-2 rounded-md bg-gray-700 hover:bg-gray-600"
>
<Link href={`/player/${player.id}`}>
<PlayerRankingMobile player={player} />
</Link>
</div>
))}
</div>
{/* Pagination */}
<div className="flex w-full flex-row justify-center rounded-md bg-gray-800 md:flex-col">
<div className="p-3">
<Pagination
currentPage={pageInfo.page}
totalPages={pageInfo.totalPages}
onPageChange={(page) => {
updatePage(page);
}}
/>
</div>
</div>
</div> </div>
)} )}
{/* Pagination */}
<div className="flex w-full flex-row justify-center rounded-md bg-gray-800 md:flex-col">
<div className="p-3">
<Pagination
currentPage={pageInfo.page}
totalPages={pageInfo.totalPages}
onPageChange={(page) => {
updatePage(page);
}}
/>
</div>
</div>
</Card> </Card>
</Container> </Container>
</main> </main>

@ -6,9 +6,11 @@ import Error from "@/components/Error";
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
import PlayerRanking from "@/components/player/PlayerRanking"; import PlayerRanking from "@/components/player/PlayerRanking";
import PlayerRankingMobile from "@/components/player/PlayerRankingMobile";
import { ScoresaberPlayer } from "@/schemas/scoresaber/player"; import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { fetchTopPlayers } from "@/utils/scoresaber/api"; import { fetchTopPlayers } from "@/utils/scoresaber/api";
import { GlobeAsiaAustraliaIcon } from "@heroicons/react/20/solid"; import { GlobeAsiaAustraliaIcon } from "@heroicons/react/20/solid";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
@ -113,7 +115,7 @@ export default function RankingGlobal() {
<GlobeAsiaAustraliaIcon width={32} height={32} /> <GlobeAsiaAustraliaIcon width={32} height={32} />
<p>You are viewing Global scores</p> <p>You are viewing Global scores</p>
</div> </div>
<table className="w-full table-auto border-spacing-2 border-none text-left"> <table className="hidden w-full table-auto border-spacing-2 border-none text-left md:table">
<thead> <thead>
<tr> <tr>
<th className="px-4 py-2">Rank</th> <th className="px-4 py-2">Rank</th>
@ -132,21 +134,34 @@ export default function RankingGlobal() {
))} ))}
</tbody> </tbody>
</table> </table>
<div className="flex flex-col gap-2 md:hidden">
{players.map((player) => (
<div
key={player.rank}
className="flex flex-col gap-2 rounded-md bg-gray-700 hover:bg-gray-600"
>
<Link href={`/player/${player.id}`}>
<PlayerRankingMobile player={player} />
</Link>
</div>
))}
</div>
{/* Pagination */}
<div className="flex w-full flex-row justify-center rounded-md bg-gray-800 md:flex-col">
<div className="p-3">
<Pagination
currentPage={pageInfo.page}
totalPages={pageInfo.totalPages}
onPageChange={(page) => {
updatePage(page);
}}
/>
</div>
</div>
</div> </div>
)} )}
{/* Pagination */}
<div className="flex w-full flex-row justify-center rounded-md bg-gray-800 md:flex-col">
<div className="p-3">
<Pagination
currentPage={pageInfo.page}
totalPages={pageInfo.totalPages}
onPageChange={(page) => {
updatePage(page);
}}
/>
</div>
</div>
</Card> </Card>
</Container> </Container>
</main> </main>

@ -0,0 +1,58 @@
import { ScoresaberPlayer } from "@/schemas/scoresaber/player";
import { useSettingsStore } from "@/store/settingsStore";
import { formatNumber } from "@/utils/number";
import ReactCountryFlag from "react-country-flag";
import { useStore } from "zustand";
import Avatar from "../Avatar";
import Label from "../Label";
type PlayerRankingProps = {
player: ScoresaberPlayer;
showCountryFlag?: boolean;
};
export default function PlayerRankingMobile({
player,
showCountryFlag = true,
}: PlayerRankingProps) {
const settingsStore = useStore(useSettingsStore, (store) => store);
return (
<div>
<div className="m-3 flex flex-col gap-2">
<p className="flex items-center gap-2">
<p>#{formatNumber(player.rank)}</p>
<Avatar url={player.profilePicture} label="Avatar" size={24} />
{showCountryFlag && (
<ReactCountryFlag
countryCode={player.country}
svg
className="!h-5 !w-5"
/>
)}
<p
className={
player.id == settingsStore?.userId
? "transform-gpu text-red-500 transition-all hover:text-blue-500"
: ""
}
>
{player.name}
</p>
</p>
<div className="flex flex-wrap justify-center gap-2">
<Label
title="PP"
hoverValue="Total amount of pp"
value={`${formatNumber(player.pp)}`}
/>
<Label
title="Total play count"
hoverValue="Total ranked song play count"
value={formatNumber(player.scoreStats.totalPlayCount)}
/>
</div>
</div>
</div>
);
}