make ranking pages mobile friendly
All checks were successful
deploy / deploy (push) Successful in 1m1s
All checks were successful
deploy / deploy (push) Successful in 1m1s
This commit is contained in:
parent
36d71d3b3a
commit
f5ac6859b8
@ -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>
|
||||||
|
58
src/components/player/PlayerRankingMobile.tsx
Normal file
58
src/components/player/PlayerRankingMobile.tsx
Normal file
@ -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>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user